Codeforces 919F. A Game With Numbers(博弈论)
Imagine that Alice is playing a card game with her friend Bob. They both have exactly 88 cards and there is an integer on each card, ranging from 00 to 44. In each round, Alice or Bob in turns choose two cards from different players, let them be aa and bb, where aa is the number on the player's card, and bb is the number on the opponent's card. It is necessary that a⋅b≠0a⋅b≠0. Then they calculate c=(a+b)mod5c=(a+b)mod5 and replace the number aa with cc. The player who ends up with numbers on all 88 cards being 00, wins.
Now Alice wants to know who wins in some situations. She will give you her cards' numbers, Bob's cards' numbers and the person playing the first round. Your task is to determine who wins if both of them choose the best operation in their rounds.
Input
The first line contains one positive integer TT (1≤T≤1000001≤T≤100000), denoting the number of situations you need to consider.
The following lines describe those TT situations. For each situation:
- The first line contains a non-negative integer ff (0≤f≤10≤f≤1), where f=0f=0 means that Alice plays first and f=1f=1 means Bob plays first.
- The second line contains 88 non-negative integers a1,a2,…,a8a1,a2,…,a8 (0≤ai≤40≤ai≤4), describing Alice's cards.
- The third line contains 88 non-negative integers b1,b2,…,b8b1,b2,…,b8 (0≤bi≤40≤bi≤4), describing Bob's cards.
We guarantee that if f=0f=0, we have ∑8i=1ai≠0∑i=18ai≠0. Also when f=1f=1, ∑8i=1bi≠0∑i=18bi≠0 holds.
Output
Output TT lines. For each situation, determine who wins. Output
- "Alice" (without quotes) if Alice wins.
- "Bob" (without quotes) if Bob wins.
- "Deal" (without quotes) if it gets into a deal, i.e. no one wins.
解题思路:
博弈论,假如说做出一个决定,之后做出的可能的决定存在先手必败,那么这个先手一定像那个状态选择,这样后手作为新的新手就一定必败。
而如果后继状态中只要有先手必胜,那么这个人一定尽量不选择这个状态。
将状态抽象成点,将可以转移到的状态之间连上有向边,就出现了一个图。
比如说这道题,可以将可能的状态(4952个)连边,当然我们要反向处理。
确定先手必胜时BFS,否则拓扑排序。
细节要好好处理,二人是不会使用0去更新的(见题目描述)。
代码:
1 #include<map> 2 #include<queue> 3 #include<cstdio> 4 #include<cstring> 5 #include<algorithm> 6 struct pnt{ 7 std::pair<int,int>sit; 8 int hd; 9 int ind; 10 int fin;//-1 先手必败 11 }p[1000000]; 12 struct ent{ 13 int twd; 14 int lst; 15 }e[10000000]; 16 std::queue<int>Q; 17 std::map<int,int>M1; 18 std::map<std::pair<int,int>,int>M2; 19 int S[10000][10]; 20 int H[10000]; 21 int tmp[10]; 22 int cnt; 23 int n,m; 24 int T; 25 int trans(int *a); 26 int indx(int sd); 27 void dfs(int x); 28 void zip(void); 29 void build(void); 30 void Bfs(void); 31 void markimp(void); 32 void addedge(void); 33 void work(void); 34 void Pre(void); 35 void ade(int f,int t); 36 int main() 37 { 38 Pre(); 39 scanf("%d",&T); 40 while(T--) 41 work(); 42 return 0; 43 } 44 void Pre(void) 45 { 46 dfs(1); 47 zip(); 48 build(); 49 Bfs(); 50 return ; 51 } 52 void dfs(int x) 53 { 54 if(x==9) 55 { 56 m++; 57 for(int i=1;i<=8;i++) 58 { 59 S[m][i]=tmp[i]; 60 H[m]=H[m]*5+tmp[i]; 61 } 62 M1[H[m]]=m; 63 return ; 64 } 65 for(int i=tmp[x-1];i<=4;i++) 66 { 67 tmp[x]=i; 68 dfs(x+1); 69 } 70 return ; 71 } 72 void zip(void) 73 { 74 for(int i=1;i<=m;i++) 75 { 76 for(int j=1;j<=m;j++) 77 { 78 p[++n].sit=std::make_pair(i,j); 79 M2[std::make_pair(i,j)]=n; 80 } 81 } 82 return ; 83 } 84 void build(void) 85 { 86 markimp(); 87 addedge(); 88 return ; 89 } 90 void Bfs(void) 91 { 92 while(!Q.empty()) 93 { 94 int x=Q.front(); 95 Q.pop(); 96 for(int i=p[x].hd;i;i=e[i].lst) 97 { 98 int to=e[i].twd; 99 if(p[to].ind==0) 100 continue; 101 if(p[x].fin==-1) 102 { 103 p[to].ind=0; 104 p[to].fin=1; 105 Q.push(to); 106 }else{ 107 p[to].ind--; 108 if(!p[to].ind&&!p[to].fin) 109 { 110 p[to].fin=-1; 111 Q.push(to); 112 } 113 } 114 } 115 } 116 return ; 117 } 118 void markimp(void) 119 { 120 int sta=M1[0]; 121 for(int i=1;i<=n;i++) 122 { 123 if(p[i].sit.first==sta) 124 { 125 p[i].fin=1; 126 Q.push(i); 127 }else if(p[i].sit.second==sta) 128 { 129 p[i].fin=-1; 130 Q.push(i); 131 } 132 } 133 return ; 134 } 135 void addedge(void) 136 { 137 for(int x=1;x<=n;x++) 138 { 139 if(p[x].fin) 140 continue; 141 for(int i=1;i<=8;i++) 142 tmp[i]=S[p[x].sit.first][i]; 143 for(int f=1;f<=8;f++) 144 { 145 if(f!=1&&tmp[f]==tmp[f-1]) 146 continue; 147 if(!tmp[f]) 148 continue; 149 int a=tmp[f]; 150 for(int t=1;t<=8;t++) 151 { 152 if(t!=1&&S[p[x].sit.second][t]==S[p[x].sit.second][t-1]) 153 continue; 154 int b=S[p[x].sit.second][t]; 155 if(!b) 156 continue; 157 int c=(a+b)%5; 158 tmp[f]=c; 159 int t0=M1[trans(tmp)]; 160 int y=M2[std::make_pair(p[x].sit.second,t0)]; 161 ade(y,x); 162 for(int i=1;i<=8;i++) 163 tmp[i]=S[p[x].sit.first][i]; 164 } 165 } 166 } 167 } 168 int trans(int *a) 169 { 170 int ans=0; 171 std::sort(a+1,a+9); 172 for(int i=1;i<=8;i++) 173 ans=ans*5+a[i]; 174 return ans; 175 } 176 void ade(int f,int t) 177 { 178 cnt++; 179 e[cnt].twd=t; 180 e[cnt].lst=p[f].hd; 181 p[f].hd=cnt; 182 p[t].ind++; 183 return ; 184 } 185 void work(void) 186 { 187 int f; 188 scanf("%d",&f); 189 int t0,t1; 190 for(int i=1;i<=8;i++) 191 scanf("%d",&tmp[i]); 192 t0=M1[trans(tmp)]; 193 for(int i=1;i<=8;i++) 194 scanf("%d",&tmp[i]); 195 t1=M1[trans(tmp)]; 196 if(f) 197 std::swap(t0,t1); 198 if(f) 199 { 200 int x=M2[std::make_pair(t0,t1)]; 201 if(p[x].fin==1) 202 { 203 puts("Bob"); 204 }else if(p[x].fin==0) 205 { 206 puts("Deal"); 207 }else{ 208 puts("Alice"); 209 } 210 }else{ 211 int x=M2[std::make_pair(t0,t1)]; 212 if(p[x].fin==-1) 213 { 214 puts("Bob"); 215 }else if(p[x].fin==0) 216 { 217 puts("Deal"); 218 }else{ 219 puts("Alice"); 220 } 221 } 222 }