题目链接:https://acm.ecnu.edu.cn/contest/196/problem/A/
题目:
解题报告:
由于必胜点是 n,所以 n 点的必胜状态为yes(走到这个点的人必胜),考虑 n-1 到 n/2+1 这一段(因为这一段都无法整除),所以 i 点的状态可以由i+1得到,接着从再从n/2推到1,由于有两种取法,所以对于当前状态 i,如果 i+1或者 2*i 的状态(这两点的状态前面已经推出来了),有一个为yes,那么这个 i 点的状态就为no(因为前面是由两者取最优的决策得出的),因为我走到这里,另一个玩家就可以从这里开始转移到下一个他必胜的状态。
所以由前面的结论,将Cuber QQ Win赢的情况的前10000项打表O(n)后,发现表中每个偶数项都能被8整除,奇数项能通过前一个偶数项+2得到。
打表代码:
1 #include<bits/stdc++.h> 2 #define numm ch-48 3 using namespace std; 4 template <typename T> 5 void read(T &res) { 6 bool flag=false;char ch; 7 while(!isdigit(ch=getchar())) (ch==‘-‘)&&(flag=true); 8 for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm); 9 flag&&(res=-res); 10 } 11 template <typename T> 12 void write(T x) { 13 if(x<0) putchar(‘-‘),x=-x; 14 if(x>9) write(x/10); 15 putchar(x%10+‘0‘); 16 } 17 typedef pair<int,int> pi; 18 typedef long long ll; 19 const int maxn=10010; 20 int a[maxn]; 21 int main() 22 { 23 int n; 24 #define local 25 #ifdef local 26 freopen("1.txt","w",stdout); 27 #endif 28 29 #define p1 puts("Little Fang Win") 30 #define p2 puts("Cuber QQ Win") 31 for(int j=2;j<=10000;j++) { 32 n=j; 33 if(n==1) { 34 p1; 35 continue; 36 } 37 if(n%2) { 38 a[n]=1; 39 n--; 40 a[n]=0; 41 for(int i=n-1;i>n/2&&i>1;i--) 42 if((n-i)%2) a[i]=1; 43 else a[i]=0; 44 } 45 else { 46 a[n]=1; 47 for(int i=n-1;i>n/2&&i>1;i--) 48 if((n-i)%2) a[i]=0; 49 else a[i]=1; 50 51 } 52 for(int i=n/2;i>1;i--) 53 a[i]=max(a[i*2],a[i+1])?0:1; 54 if(a[2]) write(j),cout<<"->",p2; 55 } 56 return 0; 57 }
然后将偶数项除以8拿出来,发现有规律的(其实口述不好说),序列是1,4,5,16,17,20,21,64,65,68,69,80,81,84,85。规律就自己看了,然后用vector打表发现存不下,后来写个算法把n往1推,发现4234这个数行不通,赛后看题解是有关二进制的,只要所有奇数位都为0,那么就是Cuber QQ Win,反之Little Fang Win,懵逼国有懵逼路,懵逼树旁懵逼树,懵逼树下只有我...
AC代码:
1 #include<bits/stdc++.h> 2 #define numm ch-48 3 using namespace std; 4 template <typename T> 5 void read(T &res) { 6 bool flag=false;char ch; 7 while(!isdigit(ch=getchar())) (ch==‘-‘)&&(flag=true); 8 for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm); 9 flag&&(res=-res); 10 } 11 template <typename T> 12 void write(T x) { 13 if(x<0) putchar(‘-‘),x=-x; 14 if(x>9) write(x/10); 15 putchar(x%10+‘0‘); 16 } 17 typedef long long ll; 18 #define p1 puts("Little Fang Win") 19 #define p2 puts("Cuber QQ Win") 20 int main() 21 { 22 int _; 23 ll n; 24 read(_); 25 while(_--) { 26 read(n); 27 bitset<64>b(n); 28 bool flag=false; 29 for(int i=0;i<63;i+=2) 30 if(b[i]) { 31 p1; 32 flag=true; 33 break; 34 } 35 if(!flag) p2; 36 } 37 return 0; 38 }
EOJ——2019.9月赛 A 才艺展示 (博弈+打表找规律)
原文:https://www.cnblogs.com/wuliking/p/11478572.html