nim游戏的规则:有两个人和 n n n堆石子,第 i i i堆石子有 a i a_i ai个,每人每次可以从任意一堆石子中取出任意多个石子。可以整堆取完,但不能不取。最后没有石子可取的人就输了。两人都用最优策略,请问是否有先手必胜的策略。
先给出结论。如果 a 1 ⊕ a 2 ⊕ ⋯ ⊕ a n ≠ 0 a_1\oplus a_2\oplus \dots \oplus a_n\neq 0 a1⊕a2⊕⋯⊕an=0,则有先手必胜策略,否则没有。
为什么呢?对于 > 0 >0 >0的情况,我们设 a 1 ⊕ a 2 ⊕ ⋯ ⊕ a n = k a_1\oplus a_2\oplus \dots \oplus a_n=k a1⊕a2⊕⋯⊕an=k,则因为 k k k二进制中的最高位是从 a a a值中来的,所以必定有一个 i i i,若 k k k二进制的最高位是第 t t t位,则 a i a_i ai二进制中的第 t t t位为 1 1 1。
我们取若干个第 i i i堆石子,使的数量变为 a i ⊕ k a_i\oplus k ai⊕k(这里可以保证 a i ⊕ k < a i a_i\oplus k
作为先手,我们只需要使得各堆石子的数量的异或和为 0 0 0。因为不能不拿,所以后手必然会使得各堆石子的异或和不为 0 0 0。我们只要在每次操作中使异或和为 0 0 0,因为石子只会越来越少,所以最后使各堆石子数量变为 0 0 0的只能是先手。
如果 a 1 ⊕ a 2 ⊕ ⋯ ⊕ a n = 0 a_1\oplus a_2\oplus \dots \oplus a_n= 0 a1⊕a2⊕⋯⊕an=0,先手不管怎么取,都会使各堆石子的异或和不为 0 0 0,只要后手每次操作都是各堆石子的异或和为 0 0 0,那后手就是最后的赢家。
结论:如果 a 1 ⊕ a 2 ⊕ ⋯ ⊕ a n ≠ 0 a_1\oplus a_2\oplus \dots \oplus a_n\neq 0 a1⊕a2⊕⋯⊕an=0,则有先手必胜策略,否则没有。
P2197 nim游戏
同上文
#include
using namespace std;
int t,n,ans,a[10005];
int main()
{
scanf("%d",&t);
while(t--){
scanf("%d",&n);
ans=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
ans^=a[i];
}
if(ans) printf("Yes\n");
else printf("No\n");
}
return 0;
}