取石子(三)(nyoj 137)

24 篇文章 0 订阅

取石子(三)

时间限制: 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

不愧是楼教主的男人八题之一……有一种不该看这道题的感觉……表示看别人写的题解都理解了好一阵子,自己想肯定想不出来。。。= =

如果石子能够两两配对,每一对中的两堆石子的个数相同,那么就是必败态,先拿的输,先拿的将必败态转化为必胜态,后拿的可以使自己拿完后仍然能够使得两两配对,且每一对的数目相同。这样就又将必败态留给对手。最后可能会变成(1, 1)的情况,这样先拿的输,后拿的赢。所以如果n是奇数的话,就不能能出现两两配对的状态那么肯定是必胜态。

结论是:如果N是奇数先手胜,如果是偶数,那么判断石子数量出现的次数是否为偶数,都是偶数那就是后者胜,只要有一个不是偶数那么先者胜。

例如4    2 1 3 2这组数据,n是偶数,1出现一次,2出现两次,3出现一次,不是所有的数出现的次数都是偶数,所以先者胜。

     4    2 1 1 2,n是偶数,1和2都出现两次,所以先者败。

#include <stdio.h>
#include <string.h>
int a[110];

int main (void)
{
	int n;
	while(scanf("%d", &n) != EOF)
	{
		memset(a, 0,sizeof(a));
		if(n == 0)
			return 0;
		int i, t;
		for(i = 0; i < n; i++)
		{
			scanf("%d", &t);
			a[t] ++;
		}
		if(n % 2 != 0)
		{
			printf("Win\n");
			continue;		
		}
		int f = 0;
		for(i = 0; i < 110; i++)
		{
			if(a[i] % 2 != 0)
			{
				printf("Win\n");
				f = 1;
				break;
			}
		}	
		if(f == 0)
			printf("Lose\n");	
	}
	return 0;
}







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值