码迷,mamicode.com
首页 > 其他好文 > 详细

EOJ——2019.9月赛 A 才艺展示 (博弈+打表找规律)

时间:2019-09-06 23:11:57      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:为我   its   序列   dig   break   max   uber   sed   就是   

题目链接: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 才艺展示 (博弈+打表找规律)

标签:为我   its   序列   dig   break   max   uber   sed   就是   

原文地址:https://www.cnblogs.com/wuliking/p/11478572.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!