2018年全国多校算法寒假训练营练习比赛(第三场) 小牛再战(博弈)
链接:https://www.nowcoder.net/acm/contest/75/F
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
共有N堆石子,已知每堆中石子的数量,两个人轮流取石子,每次只能选择N堆石子中的一堆取一定数量的石子(最少取一个),取过子之后,还可以将该堆石子中剩余的石子随意选取几个放到其它的任意一堆或几堆上。等哪个人无法取子时就表示此人输掉了游戏。注意:一堆石子没有子之后,就不能再往此处放石子了。
假设每次都是小牛先取石子,并且游戏双方都绝对聪明,现在给你石子的堆数、每堆石子的数量,请判断出小牛能否获胜。
输入描述:
可能有多组测试数据(测试数据组数不超过1000)
每组测试数据的第一行是一个整数,表示N(1<=N<=10)
第二行是N个整数分别表示该堆石子中石子的数量。(每堆石子数目不超过100)
当输入的N为0时,表示输入结束
输出描述:
对于每组测试数据,输出Win表示小牛可以获胜,输出Lose表示小牛必然会败。
示例1
输入
3 2 1 3 2 1 1 0
输出
Win Lose
分析:如果先手拿到的是两两成对的石子,如(2,2,1,1),(1,1)成对,(2,2)成对。那么就一定输。
因为后者可以做成镜像的操作,让石子依旧两两成对。
而如果先手拿到的不是两两成对的石子则可以用最大的一堆石子让其余所有的石子两两成对,就一定赢。
代码如下:
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int f[110]; int x; int main() { int n,flag; while(scanf("%d",&n)!=EOF) { if(n==0)break; flag=1; for(int i=1;i<=n;i++) { cin>>x; f[x]^=1; } for(int i=1;i<=n;i++) { if(f[x]==1) { flag=0; break; } } if(flag==1)puts("Lose"); else puts("Win"); } return 0; }