题意:给你n堆石子,每次你可以选择在一堆中取至少一颗石子,之后可以选择(也可以不选择)将一堆剩下的石子放到其他堆里面,问最后水不能取谁输。
思路:首先明确一点,当只有两堆且两两相等的时候,先手取什么后手对称取他,这样的话后手肯定赢,4堆且两两相等的时候也一样,因为我们把两两相等的两堆看成两个游戏(A,B)先手会拿A的第一颗,那么后手会拿A的最后一颗,那么之后先手就肯定只能拿B的第一颗石子,后手必定拿B的最后一颗石子,先手输。。那么对于不一样的4堆怎么办?我们取4堆中的最大值,之后让他变成4堆中最小的一个,之后我们利用最小值和最大值的差值就补平那些不一样的就好了,这样就会得到4个完全相等的,把必败局面留给了后手,,那么对于奇数堆呢,先手可以把奇数堆全部拿完,之后分到不平等的偶数堆里面,使他变成相等的奇数堆,先手还是必胜的,那么由此可以知道什么时候先手必输,就是她直接面临的是偶数堆,且偶数堆的两两相等,这样后手就可以直接模仿先手的操作了,所以说如果是奇数堆先手必胜,如果是偶数堆,判断,如果偶数堆本来就是两两相等的,那么先手必输,如果不是那么先手必赢。
上代码:
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; const int maxn = 100+10; int a[maxn]; int main() { int n; while(scanf("%d",&n)!=EOF) { if(n == 0) break; for(int i = 0 ; i < n ; i++) { scanf("%d",&a[i]); } if(n&1) puts("1"); else { sort(a,a+n); int flag = 0; for(int i = 0 ; i < n ;i +=2) { if(a[i] != a[i+1]) { flag = 1; break; } } if(flag) { puts("1"); } else { puts("0"); } } } return 0; }