HDU 4759 Poker Shuffle
Poker Shuffle
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 226 Accepted Submission(s): 78
Suppose K=2^N and the order of the cards is (1, 2, 3, …, K-2, K-1, K) in the beginning, is it possible that the A-th card is X and the B-th card is Y after several perfect shuffles?
Each case contains five integer, N, A, X, B, Y. 1 <= N <= 1000, 1 <= A, B, X, Y <= 2^N.
每次洗牌的时候,奇数在后偶数在前时,只需循环右移一下,如下:
0(000) -->0(000) -->0(000) -->0(000)
1(001) -->4(100) -->2(010) -->1(001)
2(010) -->1(001) -->4(100) -->2(010)
3(011) -->5(101) -->6(110) -->3(011)
4(100) -->2(010) -->1(001) -->4(100)
5(101) -->6(110) -->3(011) -->5(101)
6(110) -->3(011) -->5(101) -->6(110)
7(111) -->7(111) -->7(111) -->7(111)
奇数在前偶数在后时,只需右移一下,高位亦或1,如下(从右向左看):
000(0) -> 100(4) -> 110(6) -> 111(7) -> 011(3) -> 001(1) -> 000(0)
001(1) -> 000(0) -> 100(4) -> 110(6) -> 111(7) -> 011(3) -> 001(1)
010(2) -> 101(5) -> 010(2) -> 101(5) -> 010(2) -> 101(5) -> 010(2)
011(3) -> 001(1) -> 000(0) -> 100(4) -> 110(6) -> 111(7) -> 011(3)
100(4) -> 110(6) -> 111(7) -> 011(3) -> 001(1) -> 000(0) -> 100(4)
101(5) -> 010(2) -> 101(5) -> 010(2) -> 101(5) -> 010(2) -> 101(5)
110(6) -> 111(7) -> 011(3) -> 001(1) -> 000(0) -> 100(4) -> 110(6)
111(7) -> 011(3) -> 001(1) -> 000(0) -> 100(4) -> 110(6) -> 111(7)
从上面两个表可以看出,每层的任意2个数异或的结果相同,且都为n。
eg:
000(0) -> 100(4) -> 110(6) -> 111(7) -> 011(3) -> 001(1) -> 000(0)
001(1) -> 000(0) -> 100(4) -> 110(6) -> 111(7) -> 011(3) -> 001(1)
010(2) -> 101(5) -> 010(2) -> 101(5) -> 010(2) -> 101(5) -> 010(2)
每行的红色数字异或,粉红色数字异或,蓝色数字异或------>都为7,所以,你懂得
import java.math.*; import java.util.*; public class Main{ static int n; static Scanner cin = new Scanner(System.in); static BigInteger rot(BigInteger x){ BigInteger tmp = x.and(BigInteger.valueOf(1)); return x.shiftRight(1).or(tmp.shiftLeft(n-1)); } public static void main(String[] args){ int t = cin.nextInt(), cases=0; while(++cases <= t){ n = cin.nextInt(); BigInteger A = cin.nextBigInteger(), X = cin.nextBigInteger(); BigInteger B = cin.nextBigInteger(), Y = cin.nextBigInteger(); A = A.add(BigInteger.valueOf(-1)); B = B.add(BigInteger.valueOf(-1)); X = X.add(BigInteger.valueOf(-1)); Y = Y.add(BigInteger.valueOf(-1)); String ans = "No"; for(int i=0; i <= n; i++){ A = rot(A); B = rot(B); BigInteger tmpx = A.xor(X); BigInteger tmpy = B.xor(Y); if(tmpx.compareTo(tmpy)==0){ ans = "Yes"; break; } } System.out.println("Case " + cases + ": " + ans); } } }