sg函数&&子状态的讨论

题目链接:https://cn.vjudge.net/contest/269933#problem/H

具体思路:首先,这是一个公平的比赛,并且是两个人参与,两个人都足够聪明,并且可以通过有限步结束比赛,所以可以通过sg函数解决,注意这个题的不同,假设当前的某一堆堆数是5,如果分成每堆为2,他的子状态是2 2 1,和之前做过的子状态不同,之前做的题拿掉的就相当于扔掉了,而这个题并没有。

 1 #include<iostream>
 2 #include<string>
 3 #include<iomanip>
 4 #include<stack>
 5 #include<queue>
 6 #include<map>
 7 #include<vector>
 8 #include<cmath>
 9 #include<stdio.h>
10 #include<cstring>
11 using namespace std;
12 # define ll long long
13 # define maxn 2000+100
14 # define inf 0x3f3f3f3f
15 int ans[maxn];
16 int vis[maxn];
17 int main()
18 {
19     ans[0]=0;
20     for(int i=1; i<=2000; i++)
21     {
22         memset(vis,0,sizeof(vis));
23         for(int j=1; j<i; j++)
24         {
25             int temp=i/j;
26             if(temp%2==0)vis[ans[i%j]]=1;//如果按照每一堆j个,如果有2堆,那么他们的异或是0,如果有一堆,他们的异或就是本身,所以这个地方可以化简一下,直接判断奇数还是偶数就可以了。
27             else vis[ans[i%j]^ans[j]]=1;
28         }
29         for(int j=0; j<=2000; j++)
30         {
31             if(vis[j]==0)
32             {
33                 ans[i]=j;
34                 break;
35             }
36         }
37     }
38     int n;
39     int temp;
40     int t=0;
41     scanf("%d",&n);
42     for(int i=1; i<=n; i++)
43     {
44         scanf("%d",&temp);
45         t^=ans[temp];
46     }
47     if(t)printf("First\n");
48     else printf("Second\n");
49     return 0;
50 }
51  

 

posted @ 2018-11-16 16:27  Let_Life_Stop  阅读(154)  评论(0编辑  收藏  举报