hdu4371 Alice and Bob(博弈论)

Alice and Bob

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 55    Accepted Submission(s): 33


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
2
7 1
3
 
7 2
2 6
 
Sample Output
Case #1: Alice
Case #2: Bob
 
题意:Alice 和 Bob 轮流写数字,假设第 i 次的数字是 S(i) ,那么第 i+1 次的数字 S(i+1)= S(i)+d(k)或 S(i)-d(k),条件是 S(i+1)<= n && S(i-1)<S(i+1)。
分析:杂一看真的不好确定必输或必赢状态。那么直接想最后一步,什么时候就结束呢?s(i)+min > n 时就输了;那么s(i-1)又是什么情况呢?s(i-1) 可以选择一个 d(d >min) 或 min 这两种情况,如果选择了 min,那么下一步一定也要向上加,如果选择了是 d 那么有两种情况种是向下面减,和向上面加。于是可以发现先手如果选择了 min 那么后手只能向上加,如果先手选择了 d ,那么后手就可以减去 min ,这样可以保证自己永远有数可以写直到自己赢了。
 
View Code
 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 int main()
 5 {
 6     int test,n,m,tmin,t,i,k;
 7     scanf("%d",&test);
 8     for(k=1;k<=test;k++)
 9     {
10         tmin=1000000;
11         scanf("%d %d",&n,&m);
12         for(i=0;i<m;i++)
13         {
14             scanf("%d",&t);
15             if(tmin>t)
16                 tmin=t;
17         }
18         n=n/tmin;
19         if(n&1) printf("Case #%d: Bob\n",k);
20         else printf("Case #%d: Alice\n",k);
21     }
22     return 0;
23 }

 

转载于:https://www.cnblogs.com/zhourongqing/archive/2012/08/16/2642966.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值