CF 919F A Game With Numbers

很显然是一道博弈论!

那么就用搜索来解决。

首先会发现一个性质,即牌的顺序对答案是没有影响的!(简直废话

所以可以计算出所有的状态数是不超10e8的

所以可以预处理出所有状态的结果再O(1)返回答案

因为两人都不傻,所以当某一状态的后继状态出现先手必败时,此状态一定先手必胜

建图跑拓扑

若某一状态没有被更新答案

易证该状态无解(因为跑不出结果)

  1 #include<map>
  2 #include<queue>
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<algorithm>
  6 using namespace std;
  7 int n,m,t,cnt,tot,fir;
  8 int cra[9],crb[9];
  9 int a[9],b[9],c[9];
 10 int head[400010],nxt[400010];
 11 int mrk[400010],sta[400010];
 12 int rst[400010],dgr[400010];
 13 struct Edge{
 14     int fr;
 15     int to;
 16     int nxt;
 17 }edge[40000010];
 18 int HASH(int a[]){
 19     int ret=0;
 20     for(int i=1;i<=8;i++){
 21         ret=ret*5+a[i];
 22     }
 23     return ret;
 24 }
 25 void dfs(int dep,int st,int last){
 26     if(dep==9){
 27         sta[++tot]=st;
 28         mrk[st]=tot;
 29         return;
 30     }
 31     for(int i=last;i<=4;i++){
 32         dfs(dep+1,st*5+i,i);
 33     }
 34 }
 35 int get_pos(int x,int y){
 36     return (x-1)*tot+y-1;
 37 }
 38 void addedge(int f,int t){
 39     cnt++;
 40     edge[cnt].fr=f;
 41     edge[cnt].to=t;
 42     edge[cnt].nxt=head[f];
 43     head[f]=cnt;
 44 }
 45 void init(){
 46     dfs(1,0,0);
 47     memset(head,-1,sizeof(head));
 48     for(int i=1;i<=tot;i++){
 49         for(int j=1;j<=tot;j++){
 50             int sta1=sta[i];
 51             int sta2=sta[j];
 52             for(int k=8;k>=1;k--){
 53                 a[k]=sta1%5;
 54                 b[k]=sta2%5;
 55                 sta1/=5;
 56                 sta2/=5;
 57             }
 58             for(int k=1;k<=8;k++){
 59                 if(!a[k])continue;
 60                 for(int f=1;f<=8;f++){
 61                     if(!b[f])continue;
 62                     for(int g=1;g<=8;g++){
 63                         c[g]=a[g];
 64                     }
 65                     c[k]=(a[k]+b[f])%5;
 66                     sort(c+1,c+9);
 67                     int tmp=mrk[HASH(c)];
 68                     addedge(get_pos(j,tmp),get_pos(i,j));
 69                     dgr[get_pos(i,j)]++;
 70                 }
 71             }
 72         }
 73     }
 74 }
 75 void Tuopu(){
 76     queue<int>que;
 77     for(int i=2;i<=tot;i++){
 78         que.push(get_pos(i,1));
 79         rst[get_pos(i,1)]=-1;
 80     }
 81     while(!que.empty()){
 82         int s=que.front();
 83         que.pop();
 84         for(int i=head[s];i!=-1;i=edge[i].nxt){
 85             int v=edge[i].to;
 86             if(!rst[v]){
 87                 if(rst[s]==-1){
 88                     rst[v]=1;
 89                     que.push(v);
 90                 }else{
 91                     dgr[v]--;
 92                     if(!dgr[v]){
 93                         rst[v]=-1;
 94                         que.push(v);
 95                     }
 96                 }
 97             }
 98         }
 99     }
100 }
101 int main(){
102     init();
103     Tuopu();
104     scanf("%d",&t);
105     while(t--){
106         scanf("%d",&fir);
107         for(int i=1;i<=8;i++){
108             scanf("%d",&cra[i]);
109         }
110         sort(cra+1,cra+9);
111         for(int i=1;i<=8;i++){
112             scanf("%d",&crb[i]);
113         }
114         sort(crb+1,crb+9);
115         int Al=mrk[HASH(cra)];
116         int Bo=mrk[HASH(crb)];
117         if(fir==0){
118             if(!rst[get_pos(Al,Bo)]){
119                 printf("Deal\n");
120                 continue;
121             }
122             if(rst[get_pos(Al,Bo)]==1){
123                 printf("Alice\n");
124             }else{
125                 printf("Bob\n");
126             }
127         }else{
128             if(!rst[get_pos(Bo,Al)]){
129                 printf("Deal\n");
130                 continue;
131             }
132             if(rst[get_pos(Bo,Al)]==1){
133                 printf("Bob\n");
134             }else{
135                 printf("Alice\n");
136             }
137         }
138     }
139     return 0;
140 }

猜你喜欢

转载自www.cnblogs.com/lnxcj/p/9880302.html