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 }

 

posted @ 2020-05-28 10:16  WeiAR  阅读(118)  评论(0编辑  收藏  举报