标签: 思维 模拟
题意: 对于一副有2^n张牌的扑克, 标号1 ~ 2^n. 起初, 牌是有序的(1, 2, 3, 4, ...), 洗完一次牌后, 将变为(1, 3, 5, ..., 2^n - 1, 2, 4,..., 2^n) 或 (2, 4, ..., 2^n, 1, 3, 5, ..., 2^n - 1), 可以多次洗牌, 洗牌的规则总是如此反复. 现问的是, 给你n, a, x, b, y, 有没有可能在若干次洗牌后, 使得a位置的牌的值为x, b位置的牌的值为y. 其中n <= 1000.
分析:
cwz指出这种洗牌规则不符合常规, 还真是, 先不管了~~
突破点, 牌数为2^n, 明显要看数据的二进制表现.
先a = a-1, b = b-1, x = x-1, y = y-1, 便于处理.
对于牌a, 牌b, 一次洗牌后, 如果a与b同奇或同偶, 那么a, b一定会同时分到整副牌的前一半或后一半, 这点在二进制中, 相当于将a, b右移一位, 然后再在其最高位同补上一个0或一个1; 同样的如果a, b奇偶性不同, a, b一定不会同时分到整副牌的前半或后半, 那么在最高位补的数也不一样;
洗一次牌后, 等于是a,b的二进制位都右移了一位, 同时最高位又都补上一位, 补的位恰好其奇偶性是否相同的性质与右移出的那一位是一致的! 那么说, 将a, b的二进制表示数连成一个环(环中n个数对(ai, bi)), 记h(ai, bi) = (ai == bi), 洗牌若干次后, 环的h性质一直不变!
由于只是判断(a, b)到(x, y)是否有解, 意味着, 我们洗一次牌, 右移一位a, b时, 补的最高位的形式是可以随便定的, 只要h性质不变.
最后此题的作法就是, 先把a,b,x,y化成二进制, 看看是否存在一个t使得对于所有的i, 都有(a[(t + i) % n] == b[(t + i) % n]) == (x[i] == y[i]). 存在即Yes, 否则No.
#include
#include
#include