Alice and Bob
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 580 Accepted Submission(s): 356
Problem Description
Alice and Bob are interested in playing games. One day, they invent a game which has rules below:
1. Firstly, Alice and Bob choose some random positive integers, and here we describe them as n, d
1, d
2,..., d
m.
2. Then they begin to write numbers alternately. At the first step, Alice has to write a “0”, here we let s
1 = 0 ; Then, at the second step, Bob has to write a number s
2 which satisfies the condition that s
2 = s
1 + d
k and s
2 <= n, 1<= k <= m ; From the third step, the person who has to write a number in this step must write a number s
i which satisfies the condition that s
i = s
i-1 + d
k or s
i = s
i-1 - d
k , and s
i-2 < s
i <= n, 1 <= k <= m, i >= 3 at the same time.
3. The person who can’t write a legal number at his own step firstly lose the game.
Here’s the question, please tell me who will win the game if both Alice and Bob play the game optimally.
Input
At the beginning, an integer T indicating the total number of test cases.
Every test case begins with two integers n and m, which are described before. And on the next line are m positive integers d
1, d
2,..., d
m.
T <= 100;
1 <= n <= 10
6;
1 <= m <= 100;
1 <= d
k <= 10
6, 1 <= k <= m.
Output
For every test case, print “Case #k: ” firstly, where k indicates the index of the test case and begins from 1. Then if Alice will win the game, print “Alice”, otherwise “Bob”.
Sample Input
Sample Output
Case #1: Alice
Case #2: Bob
Author
standy from UESTC
Source
2012 Multi-University Training Contest 8
Recommend
zhuyuanchen520
贴一个据说是官方的思路吧.
结论:在所有的d中,选择最小的d,这里记作dmin,Alice和Bob每次都选择+dmin(写下的数是在原来的那个数上加上dmin),按照这样的策略最后的结果就是全局的结果。
可以这样考虑正确性,不妨假设按照以上策略是Alice获胜,那么Alice并不会主动改变策略;假设Bob在某一步突然改变策略,即没有选择+dmin,那么就必然选择了某个+d(不会是-d,因为这样肯定不合法),且d > dmin,那么下一步Alice就可以选择-dmin了,再下一步,Bob就只能选择某个+d,且d > dmin,Alice则可以一如既往的选择-dmin,如此循环,无论每次Bob做什么样的决策,Alice都可以选择-dmin,所以肯定是Bob最先没有选择,同样是Alice获胜。这样就证明了开头的结论。
我的理解就是说,每次每个人必须取dmin,否则对方就可以取-dmin,使得自己有步可走。
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<iostream>
#define MAXN 100+10
using namespace std;
int d[MAXN];
int s[1000010];
int main()
{
int T,i;
scanf("%d",&T);
for(i=1;i<=T;i++)
{
int n,m , dx = (1 << 29);
int j;
scanf("%d%d",&n,&m);
for(j=1;j<=m;j++)
{
scanf("%d",&d[j]);
dx = min(dx , d[j]);
}
s[1] = 0;
int k = 2;
while(s[k - 1] + dx <= n)
{
s[k] = s[k - 1] + dx;
k++;
// cout << "k =" << k << endl;
}
// cout << dx << endl;
// cout << "*" << k << "*" << endl;
printf("Case #%d: " , i);
if(k & 1)puts("Bob");
else puts("Alice");
}
}