• CF786A


      1 /*
      2  CF786A - Berzerk
      3  http://codeforces.com/contest/786/problem/A
      4  博弈论
      5  直接搜出NP状态图。记得要记忆化剪枝。
      6  *
      7  */
      8 #include <cstdio>
      9 #include <cstring>
     10 //#define tle
     11 #ifdef tle
     12 //#define test
     13 
     14 using namespace std;
     15 const int Nmax=7005;
     16 int now;
     17 int is[2][Nmax];
     18 int n;
     19 int s[2][Nmax];
     20 int tmp[2][Nmax];
     21 int k[2];
     22 #ifdef test
     23 void watch()
     24 {
     25     for(int i=0;i<=1;i++)
     26     {
     27         printf("s[%d]:
    ",i);
     28         for(int j=1;j<=n;j++)
     29             printf("%d ",is[i][j]);
     30         printf("
    ");
     31     }
     32 }
     33 #endif
     34 
     35 void work()
     36 {
     37     for(int j=0;j<=1;j++)
     38     for(int i=1;i<=k[j];i++)
     39     {
     40         int x=(n+1-s[j][i])%n;
     41         while(x<=0)
     42             x+=n;
     43         is[j][x]=1;
     44     }
     45     #ifdef test
     46     watch();
     47     #endif
     48 
     49     for(int t=1;t<=100000;t++)
     50     {
     51         for(int ii=0;ii<=1;ii++)
     52             for(int jj=1;jj<=n;jj++)
     53                 tmp[ii][jj]=is[ii][jj];
     54     for(int now=0;now<=1;now++)
     55     for(int i=2;i<=n;i++)
     56     {
     57         if(is[now][i]!=-1)
     58             continue;
     59         int flag=0;
     60         for(int j=1;j<=k[now];j++)
     61         {
     62             int x=(i+s[now][j])%n;
     63             while(x<=0)
     64                 x+=n;
     65             if(is[now^1][x]==0)
     66             {
     67                 is[now][i]=1;
     68                 flag=1;
     69                 break;
     70             }
     71             if(is[now^1][x]==-1)
     72                 flag=1;//标记不是P态
     73         }
     74         if(!flag)
     75             is[now][i]=0;    
     76 #ifdef test
     77         printf("is[%d][%d]:
    ",now,i);
     78     watch();
     79     #endif
     80     
     81     }
     82     int ff=0;
     83     for(int ii=0;ii<=1;ii++)
     84     {
     85         if(ff)
     86             break;
     87         for(int jj=1;jj<=n;jj++)
     88             if(tmp[ii][jj]!=is[ii][jj])
     89             {
     90                 ff=1;
     91                 break;
     92             }
     93     }
     94     if(!ff)
     95         break;
     96     }
     97 
     98 }
     99 
    100 void init()
    101 {
    102     for(int i=1;i<=n;i++)
    103         is[0][i]=is[1][i]=-1;
    104     is[0][1]=is[1][1]=1;
    105 }
    106 int main()
    107 {
    108     scanf("%d",&n);
    109     for(int i=0;i<=1;i++)
    110     {
    111         scanf("%d",&k[i]);
    112         for(int j=1;j<=k[i];j++)
    113             scanf("%d",&s[i][j]);
    114     }
    115     init();
    116     work();
    117     for(int t=0;t<=1;t++)
    118     {
    119         for(int i=2;i<=n;i++)
    120         {
    121             if(i!=2)
    122                 printf(" ");
    123             if(is[t][i]==-1)
    124                 printf("Loop");
    125             else if(is[t][i]==0)
    126                 printf("Lose");
    127             else
    128                 printf("Win");
    129         }
    130         printf("
    ");
    131     }
    132 }
    133 #endif
    134 
    135 using namespace std;
    136 const int Nmax=7005;
    137 int now;
    138 int is[2][Nmax];
    139 int n;
    140 int s[2][Nmax];
    141 int tmp[2][Nmax];
    142 int k[2];
    143 
    144 void dfs(int now,int x,int sstatus)
    145 {
    146     if(is[now][x]!=-1)//如果已经有状态了,返回
    147         return;
    148     is[now][x]=sstatus;
    149     if(sstatus==0)//如果当前点为必败态,则让与其相接的点为必胜态
    150     {
    151         for(int i=1;i<=k[now^1];i++)
    152         {
    153             int next=(x-s[now^1][i])%n;
    154             while(next<=0)
    155                 next+=n;
    156             dfs(now^1,next,1);
    157         }
    158     }
    159     if(sstatus==1)//如果当前点为必胜态,则让与其相接的点的非必胜态边个数-1
    160     {
    161         for(int i=1;i<=k[now^1];i++)
    162         {
    163             int next=(x-s[now^1][i])%n;
    164             while(next<=0)
    165                 next+=n;
    166             tmp[now^1][next]--;//利用tmp数组记录当前相接的点的非必胜态个数来剪枝,如果相邻点都是必胜态,则当前点为必败态
    167             if(!tmp[now^1][next])
    168                 dfs(now^1,next,0);
    169         }
    170     }
    171 }
    172 
    173 void init()
    174 {
    175     for(int i=1;i<=n;i++)
    176         is[0][i]=is[1][i]=-1;
    177     is[0][1]=is[1][1]=0;
    178 }
    179 int main()
    180 {
    181     scanf("%d",&n);
    182     for(int i=0;i<=1;i++)
    183     {
    184         scanf("%d",&k[i]);
    185         for(int j=1;j<=k[i];j++)
    186             scanf("%d",&s[i][j]);
    187         for(int j=1;j<=n;j++)
    188             tmp[i][j]=k[i];
    189     }
    190     init();
    191     for(int j=0;j<=1;j++)
    192     for(int i=1;i<=k[j];i++)
    193     {
    194         int x=(n+1-s[j][i])%n;
    195         while(x<=0)
    196             x+=n;
    197         dfs(j,x,1);
    198     }
    199     for(int t=0;t<=1;t++)
    200     {
    201         for(int i=2;i<=n;i++)
    202         {
    203             if(i!=2)
    204                 printf(" ");
    205             if(is[t][i]==-1)
    206                 printf("Loop");
    207             else if(is[t][i]==0)
    208                 printf("Lose");
    209             else
    210                 printf("Win");
    211         }
    212         printf("
    ");
    213     }
    214     return 0;
    215 }
  • 相关阅读:
    手机端网页web开发要点
    js javascript:void(0) 真正含义
    牛客第二场 C.message(计算几何+二分)
    计算几何_三维凸包
    【kuangbin专题】计算几何_半平面交
    【kuangbin专题】计算几何_凸包
    【kuangbin专题】计算几何基础
    Codeforces 1058 D. Vasya and Triangle(分解因子)
    网络流模板
    2018 Multi-University Training Contest 6
  • 原文地址:https://www.cnblogs.com/BBBob/p/6612753.html
Copyright © 2020-2023  润新知