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


    题目链接: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 }
    代码在这里!
  • 相关阅读:
    volatile用法
    static用法
    sizeof用法
    C语言void关键字的深刻含义
    extern用法
    const用法
    attribute用法
    Task的运行过程分析
    Android BroadcastReceiver实例Demo(有序广播的发送)
    旅行-许巍
  • 原文地址:https://www.cnblogs.com/wuliking/p/11478572.html
Copyright © 2020-2023  润新知