zoukankan      html  css  js  c++  java
  • Codeforces Round #652 (Div. 2) F. BareLee(博弈论)

    题目: 传送门 

    思路: 根据最后一轮的输赢推出最后一轮的先后手(看先手必赢还是后手必赢或者看先手必输还是后手必输),再推出上一轮的输赢(输赢-->先后手);

        那么如何判断每一轮是先手可以必赢还是后手可以必赢呢?

        若e为奇数, s为偶数,先手必赢,否则后手必赢(若是偶数,先手一直加一即可,后手只能把奇数变成偶数);

        若e为偶数,s>e/2 (这样就只能执行+1操作) , s为奇数,先手必赢(先手+1操作后恒为偶),否则后手必赢 (s为奇数);

               e/4<s<=e/2 , 先手必赢 (直接乘以2,变成上一种情况的必赢态) ;

               s<=e/4 , 若[s , e/4] 先手可以必赢,那么[s,e] 先手可以必赢(  下一次先手操作的数字一定是 属于区间(e/4,e/2]  ),否则后手必赢 ;

        判断先手必输:

        若 s>e/2 (e>0) , 则先手可以必输。

        否则 ,若 [s,e/2] 先手可以必赢,那么[s,e] 先手可以必输,若不能必赢,则后手可以必输。

    接下来就是代码实现了(里面有较为详细的注释)

     1 #include<bits/stdc++.h>
     2 /*
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<cstring>
     6 #include<vector>
     7 #include<cctype>
     8 #include<queue>
     9 #include<algorithm>
    10 #include<map>
    11 #include<set>
    12 */
    13 #pragma GCC optimize(2)
    14 using namespace std;
    15 typedef long long LL;
    16 typedef unsigned long long uLL;
    17 typedef pair<int,int> pii;
    18 typedef pair<LL,LL> pLL;
    19 typedef pair<double,double> pdd;
    20 const int N=2e6+5;
    21 const int M=1e4+5;
    22 const int inf=0x3f3f3f3f;
    23 const LL mod=1e9+7;
    24 const double eps=1e-5;
    25 const long double pi=acos(-1.0L);
    26 #define ls (i<<1)
    27 #define rs (i<<1|1)
    28 #define fi first
    29 #define se second
    30 #define pb push_back
    31 #define mk make_pair
    32 #define mem(a,b) memset(a,b,sizeof(a))
    33 LL read()
    34 {
    35     LL x=0,t=1;
    36     char ch;
    37     while(!isdigit(ch=getchar())) if(ch=='-') t=-1;
    38     while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
    39     return x*t;
    40 }
    41 int l[N],w[N];//l lose 表示先手能不能必输 1先手可以必输,w win 表示先手能不能必赢 1先手可以必赢
    42 int check(int i,int flag)//flag表示这一轮的输赢 1赢 0输
    43 {
    44     if(i==1)
    45     {
    46         if(flag) return w[i];
    47         else return l[i];
    48     }
    49     if(flag) return check(i-1,!w[i]);//这一轮赢
    50     /*{
    51         if(w[i]) return check(i-1,0); //如果这一轮是先手赢,上一轮一定是要输
    52         else return check(i-1,1); //如果这一轮是后手赢,那么上一轮就要赢
    53     }*/
    54     else return check(i-1,!l[i]);
    55 }
    56 int dfs(LL s,LL e)//判断先手能否必赢
    57 {
    58     if(e&1)
    59     {
    60         if(s&1) return 0;
    61         else return 1;
    62     }
    63     else
    64     {
    65         if(s>e/2)
    66         {
    67             if(s&1) return 1;
    68             else return 0;
    69         }
    70         else if(s>e/4) return 1;
    71         else return dfs(s,e/4);
    72     }
    73 }
    74 int dfs2(LL s,LL e)//判断先手能否必输
    75 {
    76     if(s>e/2) return 1;
    77     else return dfs(s,e/2)==1;//[s,e/2]先手必赢,才能有[s,e]先手必输。先手必赢那么接下来,后手操作完的a一定是>e/2,先手再乘以2就ok
    78 }
    79 int main()
    80 {
    81     int n=read();
    82     for(int i=1;i<=n;i++)
    83     {
    84         LL s=read(),e=read();
    85         w[i]=dfs(s,e);
    86         l[i]=dfs2(s,e);
    87         //printf("w = %d , l = %d
    ",w[i],l[i]);
    88     }
    89     printf("%d %d
    ",check(n,1),check(n,0));
    90     return 0;
    91 }
    View Code
  • 相关阅读:
    P3899 [湖南集训]谈笑风生
    bzoj3252: 攻略
    批量创建用户20个和密码
    创建100个目录dir1-dir100一键完成
    SVM的优缺点
    Python zip() 函数
    经典博客4
    python的空格和tab混用报错问题
    Python的functools.reduce用法
    matplotlib显示AttributeError: 'module' object has no attribute 'verbose'
  • 原文地址:https://www.cnblogs.com/DeepJay/p/13275492.html
Copyright © 2011-2022 走看看