POJ 1740
POJ 1740
先手必败状态为 偶数堆且为从小到大排序后(1,2)相等,(3,4)相等...,可以理解为每一堆都有与它对称的一堆
解释:在这种情况下,先手无论什么操作,后手都可以执行对称的操作,从而维持先手必败状态,而且总数量是减少的,所以先手必败
其他状态都是先手必胜状态
如果为奇数堆
解释:先从小到大排序,然后用最大的那一个填平所有(1,2),(3,4)...之间的差距,补完之后多出的部分全拿走。
证明能填满:看这个图,红色区间指需要填平的地方,因为已经排序了,所以它们不会重叠,总长度加起来不会超过最大的长度
如果为偶数
解释:先从小到大排序,然后用(最大的-最小的)填平所有(1,2),(3,4)...之间的差距,补完之后多出的部分全拿走。
证明同理。
1 #include <bits/stdc++.h> 2 #define inf 2333333333333333 3 #define N 1000010 4 #define p(a) putchar(a) 5 #define For(i,a,b) for(int i=a;i<=b;++i) 6 7 using namespace std; 8 int n,flag; 9 int a[N]; 10 void in(int &x){ 11 int y=1;char c=getchar();x=0; 12 while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();} 13 while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();} 14 x*=y; 15 } 16 void o(int x){ 17 if(x<0){p('-');x=-x;} 18 if(x>9)o(x/10); 19 p(x%10+'0'); 20 } 21 22 signed main(){ 23 while(cin>>n && n){ 24 flag=0; 25 For(i,1,n) in(a[i]); 26 if(n&1){ 27 o(1);p('\n'); 28 continue; 29 } 30 else{ 31 sort(a+1,a+n+1); 32 for(int i=2;i<=n;i+=2) 33 if(a[i]!=a[i-1]){ 34 flag=1; 35 break; 36 } 37 if(flag) o(1); 38 else o(0); 39 p('\n'); 40 } 41 } 42 return 0; 43 }