本文搬运自本人初中博客园博客,若图片加载不出来,可到原文查看:https://www.cnblogs.com/zhangtingxi/p/16004931.html
题目
N 堆石子,两人轮流从其中一堆取至少一个石子,问先手是否存在必胜策略。
结论
异或不为0,先手必胜。
证明
设 k 为某一堆取完后的剩余个数,i 为被取那堆石子的编号,则取完后的异或和为 x1xorx2xor…xorxi−1xorxi+1xor…xorxnxork。
情况一:异或和为0
- 总数为0,此时先手输了
- 总数不为0,此时先手还要使异或和为0,就必须使得 k=xi,然而由于至少取一个,所以这是不可能的,所以必然会转为情况二。
情况二:异或和不为0
可以证明,必然可以取为0。
设 S=x1xorx2xor…xorxn,xi 为 x 中的最大值。
- S 的二进制位数小于 xi 的位数,则 xi 必然可以凑出一个数使得其异或 S 等于0。
- S 的二进制位数和 xi 的二进制位数相同,需满足 k⩽xi 且 Sxorxixork=0。由于 Sxorxi 时已经使得二进制最高位为0,所以 k 的二进制最高位必然为0。k 在二进制的最高位已经满足小于 xi,后面的位数可以随便取,那么只需要取 Sxorxi 即可(这个数的二进制最高位也为0)。
代码
1 2 3 4 5 6 7 8 9 10 11
| #include<bits/stdc++.h> using namespace std; int n, m, i, j, k, T;
int main() { scanf("%d", &n); for(i=1; i<=n; ++i) scanf("%d", &k), m^=k; printf(m ? "win" : "lose"); return 0; }
|