Description
Tom和Jerry是好朋友,他们俩打算玩一个游戏来决定谁请客吃饭,输的人将付饭钱。
游戏规则如下:给定n和k,Tom和Jerry轮流说数字(Jerry先说,且说的第一个数字T,要求 1<=T<=k )。
假定前一个人说的数字为X,当前这个人说的数字为Y,要求 1<=Y-X<=k ,如此循环往复。
最先说出不小于 n 的数的人即为败者。
假定两人都很聪明,都将采取最优策略,你能告诉我谁将付饭钱么?
Input
输入有多组数据 每组有两个数字n(0<n<10^8)和k(0<k<100),当n和k都为0时停止。
Output
输出要付饭钱的人“Tom”或者“Jerry”
Sample Input
1 1
30 3
10 2
0 0
Sample Output
Jerry
Tom
Jerry
分析:
先看一些简单的情况:(n=X后面的括号为败者,即输出结果)
(1)k=1时:n=1(Jerry),n=2(Tom),n=3(Jerry),n=4(Tom)...n=奇数(Jerry),n=偶数(Tom)
(2)k=2时:n=1(Jerry),n=2(Tom),n=3(Tom),n=4(Jerry),n=5(Tom),n=6(Tom),n=7(Jerry)
(3)k=3时:n=1(Jerry),n=2(Tom),n=3(Tom),n=4(Tom),n=5(Jerry),n=6(Tom),n=7(Tom),n=8(Tom),n=9(Jerry)
从上面我们能发现一点小规律,n=1时,Jerry一定会输,随着n的增大,接下来的k个数,都是Tom输,然后又出现一个Jerry输,然后接下来的k个数,又是Tom输...
那这个规律是否就是一般的规律呢?我们详细分析一下:定义输出结果为F(n,k),比如F(1,1)=Jerry,F(1,2)=Tom......对一般的情况,n=1时,不管k为何值,F(1,k)=Jerry;当1<n<=k+1时,只要Jerry说的数字为n-1,那么Tom一定输,即1<n<=k+1时,F(n,k)=Tom;当n=k+2时,如果Jerry说的数字为T,则Tom只要说的数字为n-1(满足1<=(n-1)-T<=k),则Jerry一定输,即n=k+2时,F(n,k)=Jerry;当k+2<n<=2*k+2时,只要Jerry说的数字为k,Tom不管说的数字为何值,都会输,比如Tom说的是Y(1<=Y-k<=k),则Jerry第二次说时,只要说的数字为n-1即可(为何可以请读者自己考虑),即k+2<n<=2*k+2时,F(n,k)=F(n-(k+1),k);同理可推得,当(m-1)*k+2<n<=m*k+2时,F(n,k)=F(n-(m-1)*(k+1),k)。
综上可得,当n%(k+1)=1时,Jerry一定输,其他情况下,一定是Tom输。
代码如下:
#include <iostream>
using namespace std;
int main()
{
long long n,k;
while(cin>>n>>k)
{
if(n==0&&k==0)
break;
if(n%(k+1)==1)
cout<<"Jerry"<<endl;
else
cout<<"Tom"<<endl;
}
}