J Cunning Friends
三个人的nim博弈有趣有趣
我的思考过程如下
-
全是1的时候,n如果能整除3,那么必输,否则必赢
-
只有一个不是1的时候 ,如果n%3 == 0 ,就把不是1的取成1,这样对于第二个人必输,如果 n%3 == 1||n%3 == 2 取走不是1的一堆必赢
-
如果有小于n-2 个1,那么根据nim博弈,后面两个人总是能轻松的转移到任何状态,这时候 第一个人必输
-
通过上面的讨论我们n%3 是一个必输态,我们必须避免这种状态
-
如果有n-2个1,剩下至少有一个2,
-
如果 n% 3 == 0 ,我们把 最后一堆取的只剩下一个,这样剩下的状态等价于 n % 3 == 1,如果 取走一个2的堆或这一个1的堆,都不能改变n%3 == 1,如果取走2的堆里面的一个,那么这样就是 n%3 == 2 的状态还是必赢如果 n% 3 == 0 ,我们把 最后一堆取的只剩下一个,这样剩下的状态等价于 n % 3 == 1,如果 取走一个2的堆或这一个1的堆,都不能改变n%3 == 1,如果取走2的堆里面的一个,那么这样就是 n%3 == 2 的状态还是必赢
-
如果 n% 3 == 1,那么我们把最后一个取完,这样剩下两个人可以把状态改变成 n%3 == 2,或者保持n% 3==1这样都是必胜态
-
如果 n% 3 == 2,无论怎么取,剩下一个人都可以转化成n%3 == 0
代码参考
1.全是1时候 n%3 == 2||n%3==1都是必胜
9. 只有一个不是1的时候 必胜
10. 1,1,2,2
bool solve(int a,int b,int n){
if(a < n-2) return 0;
if(a == n)
return (n%3 != 0);
if(a == n-1) return 1;
if(n%3 != 2&& b) return 1;
return 0;
}
int main(void)
{
int n;
int a;
cin>>n;
int cnt1 = 0;
int cnt2 = 0;
rep(i,1,n+1){
scanf("%d",&a);
if(a == 1) cnt1++;
else if(a == 2) cnt2++;
}
if(solve(cnt1,cnt2,n))
puts("Win");
else
puts("Lose");
return 0;
}