1 /**
2 大意: 有1-K 张牌, 有两种洗牌方式,一种奇数在前,一种偶数在前。。
3 问结果多次洗牌之后,是否可以到达这种状态; a位置是x , b位置是y
4 若是输出yes, 否则输出no
5
6 思路: 将其转化为二进制。。。
7 ————————————————————————————————————————————————————————
8 二进制的运用。
9 题目给的牌编号是从一开始的,要先将其转成从0开始的。
10 一开始的编号是0~2^N-1,每次洗牌的过程如下:
11 第一种洗牌:将奇数放前面,偶数放后面。每个位置的数的变化相当于二进制数右移一位(相当于除以2),然后最高位异或1。
12 第二种洗牌:将偶数放前面,奇数放后面。每个位置的数的变化相当于二进制数右移一位(相当于除以2),然后最高位异或0。
13 这样就把位置为i的牌,经过一次洗牌后的位置算出来了。
14 例如: 牌: 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
15 位置: 0 1 2 3 4 5 6 7 变成 4 0 5 1 6 2 7 3
16 二进制: 000 001 010 011 100 101 110 111 100 000 101 001 110 010 111 011
17 上面的是第一种洗牌方式,可以看出奇数在前,偶数在后。
18 下面是第一种洗牌的规律:
19 000(0) -> 100(4) -> 110(6) -> 111(7) -> 011(3) -> 001(1) -> 000(0)
20 001(1) -> 000(0) -> 100(4) -> 110(6) -> 111(7) -> 011(3) -> 001(1)
21 010(2) -> 101(5) -> 010(2) -> 101(5) -> 010(2) -> 101(5) -> 010(2)
22 011(3) -> 001(1) -> 000(0) -> 100(4) -> 110(6) -> 111(7) -> 011(3)
23 100(4) -> 110(6) -> 111(7) -> 011(3) -> 001(1) -> 000(0) -> 100(4)
24 101(5) -> 010(2) -> 101(5) -> 010(2) -> 101(5) -> 010(2) -> 101(5)
25 110(6) -> 111(7) -> 011(3) -> 001(1) -> 000(0) -> 100(4) -> 110(6)
26 111(7) -> 011(3) -> 001(1) -> 000(0) -> 100(4) -> 110(6) -> 111(7)
27 可以看出,经过若按同一种洗牌方式,经过2*n次洗牌后,牌堆会恢复到原来的序列。
28 但是题目有两种洗牌方式,是反过来的,所以只要经过n次洗牌后就会恢复原来的序列了。
29 也就是说对于一堆2^n的牌,最多只有n种不同的序列,也就是最多右移n位,超过n位就会重复了。
30
31 经过若干次洗牌,可以看成是右移了k位,然后异或上一个数。
32 所以首先将A X B Y都减一,然后枚举X,Y右移k位以后,能不能同时异或上相同的数得到A,B。
33 由于a^b=c,可以得到a^c=b
34 解法总结如下:
35 从1到n枚举右移X,Y,每次判断X^A是否等于Y^B。
36 n比较大,要用大数。
37 用java大数来处理比较方便。
38 ——————————————————————————————————————————————————————————————
39 **/
40 import java.io.*;
41 import java.util.*;
42 import java.math.*;
43
44 public class Main{
45 static int n;
46 // 为什么是循环右移???---->只考虑了偶在前奇在后
47 public static BigInteger right(BigInteger a){
48 BigInteger tmp = a.and(BigInteger .ONE );
49 return a.shiftRight(1).or(tmp.shiftLeft(n-1));
50
51 }
52
53 public static void main(String[] args) {
54 int i,t,k,flag;
55 BigInteger A,B,X,Y,a,b;
56 Scanner cin = new Scanner(System. in);
57 t = cin.nextInt();
58 for(i=1;i<=t;i++){
59
60 n = cin.nextInt();
61 A = cin.nextBigInteger();
62 X = cin.nextBigInteger();
63 B = cin.nextBigInteger();
64 Y = cin.nextBigInteger();
65 //System.out.println(A+" "+X+" "+ B+ " "+ Y);
66 A = A.add( BigInteger.valueOf(-1));
67 X = X.add( BigInteger.valueOf(-1));
68 B = B.add( BigInteger.valueOf(-1));
69 Y = Y.add( BigInteger.valueOf(-1));
70 //System.out.println(A+" "+X+" "+ B+ " "+ Y+"-------------->");
71 flag =0;
72 for(k=1;k<=2*n;k++){
73
74 X = right(X);
75 Y = right(Y);
76 a = X.xor(A);
77 b = Y.xor(B);
78 if(a.equals(b)){
79 flag =1;
80 break;
81 }
82 }
83 //System.out.println(flag+"************");
84 if(flag==1)
85 System. out.println("Case " +i+": Yes" );
86 else
87 System. out.println("Case " +i+": No" );
88 }
89 }
90 }