就拿石头(三)
时间限制:1000 ms | 内存限制:1000 KB
难度:6
描写叙述
小王喜欢与同事玩一些小游戏,今天他们选择了玩取石子。
游戏规则例如以下:共同拥有N堆石子,已知每堆中石子的数量,两个人轮流取子,每次仅仅能选择N堆石子中的一堆,取一定数量的石子(最少取一个),取过子之后。还能够将该堆石子中剩下的随意多个石子中随意选取几个放到其他的随意一堆或几堆上。
等哪个人无法取子时就表示此人输掉了游戏。
注意,一堆石子没有子之后。就不能再往此处放石子了。
如果每次都是小王先取石子,而且游戏两方都绝对聪明,如今给你石子的堆数、每堆石子的数量,请推断出小王是否能获胜。
比如:假设最開始有4堆石子。石子个数分别为3 1 4 2。而小王想决定要先拿走第三堆石子中的两个石子(石子堆状态变为3 1 2 2)。然后他能够使石子堆达到的状态有下面几种:
3 1 2 2(不再移动石子)
4 1 1 2(移动到第一堆一个)
3 2 1 2(移动到第二堆一个)
3 1 1 3(移动到第四堆一个)
5 1 0 2(所有移动到第一堆)
3 3 0 2(所有移动到第二堆)
3 1 0 4(所有移动到最后)
输入
可能有多组測试数据(測试数据组数不超过1000)
每组測试数据的第一行是一个整数。表示N(1<=N<=10)
第二行是N个整数分别表示该堆石子中石子的数量。
(每堆石子数目不超过100)
当输入的N为0时。表示输入结束
输出
对于每组測试数据,输出Win表示小王能够获胜。输出Lose表示小王必定会败。
例子输入
3
2 1 3
2
1 1
0
例子输出
Win
Lose
思路:
用的是尼姆博弈的一个定理:
仅仅要是存在奇数个同样的堆数,那就是必胜态。
代码例如以下:
<span style="font-size:14px;">#include<stdio.h> #include<string.h> int a[110];//a数组用来统计每一个堆数出现的次数。int ok(int *a)//推断是否是神秘局势,仅仅要存在一个奇数的堆数,就可以判定是非神秘堆数(必胜态)。 { for(int i=0;i<110;i++) if(a[i]&1) return 1; return 0; } int main() { int n,i,m; while(~scanf("%d",&n),n) { memset(a,0,sizeof(a)); for(i=0;i<n;i++) { scanf("%d",&m); a[m]++; } printf("%s ",ok(a)?"Win":"Lose"); } return 0; </span>
版权声明:本文博主原创文章,博客,未经同意不得转载。