(QUSTOJ) Problem 1681 : AMMO 最佳对策问题

问题 B: AMMO

时间限制1Sec  内存限制128 MB

题目描述

Richard和Dick是两名绝地潜兵,他们俩要领取弹药,他们决定玩一个取弹药的游戏:两人轮流取弹药,每次最少取一份,最多取m份,弹药总份数为n,约定先取光弹药的人获胜。 

输入

输入第一行为T,表示他们进行了T个回合,即有T组输入数据1<=T<=100

每组第一行为一个整数,代表游戏顺序,1表示Richard先取,0表示Dick先取

第二行为两个整数,m和n,1≤m≤n≤1000

输出

每组数据输出一行,为获胜者的名字

样例输入

3

1

15 100

0

1 5

1

1 3

样例输出

Richard

Dick

Richard

 

以前我总是不知道怎么解决这一类问题,比赛的时候看见就直接丢掉了。后来才知道这原来是一道奥数题...

来自http://www.1010jiajiao.com/xxsx/shiti_id_cee7a23fd3dfd29dda9176821968438d

题目是这样的

有47根火柴,两人轮流来取,每次最多取5根,最少取1根,谁最后把火柴取完谁就算胜利了,现在由甲先取,乙应如何取胜?

以下是解答

考点:最佳对策问题
专题:数学游戏与最好的对策问题
分析:从乙拿到第47根火柴着手,进行倒推,就能找到乙保证获胜的方法.
解答: 解:47÷6=7…5
若是余数是6,则乙取胜,
让甲先取,甲取1根,则乙就取5根,甲取2根,则乙就取4根,甲取3根,则乙就取3根,保证一个回合两个人取的火柴数是6,其中的一个回合,乙少拿1根,这样就能保证最后能剩下47-6×6-5=6根,则此时无论甲取1根至5根,都由乙取到最后.
答:让甲先取,并保证每个回合两个人取到的火柴和是6,其中有一次乙少拿1根,即可保证乙赢.
点评:此题解答的规律是:只要保证最后一个回合的根数和为6就行.

(后来我还在百度上看见一个中学课件讲这个的...丢人啊)

简单来说,对于这道题就是判断n%(m+1)!=0是否成立,如果成立的话就说明先取子弹的人最终获胜。

以第一个样例展示:

100/(1+15)=6...4,那么第一个取的人只需要取4个,接下来第二个人取k个,第一个人就取6-k个,取到最后子弹的一定是最开始取的人。

如果n%(m+1)==0那么情况就正好反过来了。


代码如下:

#include <iostream>
using namespace std;
int main()
{
    int t;
    cin>>t;
    int m,n;
    int start;
    for(int i=0;i<t;i++)
    {
        cin>>start>>m>>n;
        if(n%(m+1))
        {
            if(start)
            {
                cout<<"Richard"<<endl;
            }
            else
            {
                cout<<"Dick"<<endl;
            }
        }
        else
        {
            if(start)
            {
                cout<<"Dick"<<endl;
            }
            else
            {
                cout<<"Richard"<<endl;
            }
        }
    }
    return 0;
}


你可能感兴趣的:(最佳对策问题)