1207: 取宝石
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 39 Solved: 9
[ Submit][ Status][ Web Board]
Description
Input
Output
对于每组测试数据,输出1行,若Jerry能获胜,输出“Yes”,否则输出“No”。
Sample Input
2 1 3
2
1 1
0
Sample Output
No
【分析】
讲真这种博弈我就只会找规律.....
从最小的开始考虑,如果每个盘子上的宝石都是1,那么总数为奇数的时候Jerry一定获胜
如果两个人每次都只把一个盘子上的宝石取完,那么总数为奇数的时候Jerry一定获胜
在这两个最简单的情况下,猜测盘子是奇数是Jerry会获胜....
那么模拟正常情况,如果不是全1,那么显然不管你怎么拿,Jerry保证每次拿完宝石后将场上有宝石的盘数补全成奇数个就可以了。
那么这种情况下的最基础的情况就是盘中的宝石数量只有1和2,因为1拿完就没有了,2只能留下自己或者拿完,宝石数如果大于2就可以往外补全。
那么如果不是全1,考虑1 1 1 1 2这个情况,那么显然Jerry拿光2就可以获胜,
那么再考虑1 1 1 2 2 这个情况,那么显然Jerry拿1,然后模仿Tom拿就可以了
所以1 1 2 2 2情况类似第一种,Jerry拿掉一组2 然后跟着Tom就可以了。
之后的情况都类似上面的情况。
所以可以发现,当盘子总数为奇数的时候,Jerry一定获胜。
那么当盘子总数为偶数时,
考虑最简单的一种情况就是2 2,发现这个情况下Jerry是会输的,然后继续考虑2 3,发现Jerry可以获胜,因为2 2的情况后手获胜,所以在2 X的情况Jerry只要拿成2 2就可以获胜。
3 3也一样,所以在只有两个盘子的情况下,如果两个盘上的宝石数量一样,那么Jerry就会失败,其他情况都可以获胜。
那么再做一次猜测,盘子数量是偶数时,只有盘中宝石数全部一样,Jerry才会失败。
那么考虑2 2 2 2这种情况,这种情况下Jerry是必败的,因为不管Jerry怎么拿,Tom只要模仿就可以了。
(但是事实证明提交之后是WA的....所以也就是考虑的情况有问题....)
再考虑2 2 2 3这种情况,可以发现,2 2 2 2是先手失败,那么2 2 2 3,Jerry只要拿走3中的一个1,变成2 2 2 2,Jerry就能获胜
所以再考虑2 2 3 3这种情况,这种情况下,Tom只要模仿Jerry就可以获胜。
所以发现了之前的问题,也就是说并不是全部宝石数一样的时候会失败,而是每种宝石数成对出现的时候会失败,也就是每种宝石出现次数为偶数的时候,所以也可以回过头去证明当盘子总数是奇数的时候Jerry会获胜...
所以代码很简单....
如果盘数n是奇数,那么Jerry获胜
如果盘数n是偶数,那么排序之后判断一下每个i和i+1是否一样就可以(i为从0开始的偶数),如果出现不一样的情况就Jerry就可以获胜。否则Tom获胜
以上是一只菜鸡做这题的心路历程.......感觉自己真的菜.......继续学习...希望以后能写出比较有水准的题解...
【代码】
#include <stdio.h>
#include <algorithm>
using namespace std;
int a[10000];
int main()
{
int n;
while (~scanf("%d",&n)&&n)
{
for (int i=0;i<n;i++) scanf("%d",&a[i]);
if (n%2)
printf("Yes\n");
else
{
sort(a,a+n);
for (int i=1;i<n;i+=2)
if (a[i]!=a[i-1])
{
printf("Yes\n");
goto out;
}
printf("No\n");
out:;
}
}
return 0;
}