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 ab0a⋅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 (1T1000001≤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 (0f10≤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 (0ai40≤ai≤4), describing Alice's cards.
  • The third line contains 88 non-negative integers b1,b2,,b8b1,b2,…,b8 (0bi40≤bi≤4), describing Bob's cards.

We guarantee that if f=0f=0, we have 8i=1ai0∑i=18ai≠0. Also when f=1f=1, 8i=1bi0∑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 }

 

posted @ 2018-10-26 17:07  Unstoppable728  阅读(344)  评论(0编辑  收藏  举报