题目大意:给出数n、k,及n个数,求是否能通过对每个数加0或者k的整数倍的数,使得最终构成1--n的序列
解题思路:用一个数组exit[]标记原数列中是否直接有最终序列所需要的数,用cnt[]数组记录最终数列没有直接需要的原数列中的数的个数,然后扫描1--n的数是否都能被构成
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <list>
using namespace std;
const int maxn = 100+10;
int num[maxn],cnt[maxn],exi[maxn];
int main()
{
int t,n,k;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
memset(exi,0,sizeof(exi)); //标记原来的数里面是否已存在对应的数
memset(cnt,0,sizeof(cnt)); //计算多余的数相对应的数量
for(int i = 1; i <= n; i++)
{
scanf("%d",&num[i]);
if(!exi[num[i]])
exi[num[i]] = 1;
else
cnt[num[i]]++;
}
int flag = 0; //标记是否有某个数不能被构成
for(int i = 1; i <= n; i++) //对于要构造的1--n
{
if(!exi[i]) //若该数在原数列里不存在
{
int ok = 0; //标记该数i是否能构成
for(int j = 1; i-j*k >= 1; j++) //设原数列里有x,若能构成i,则有x+j*k=i;不断枚举j以及比i小的x
{
if(cnt[i-j*k]) //若存在一个x使得i能构成
{
ok = 1;
cnt[i-j*k]--;
break;
}
}
if(!ok) //若对于所有的x都不能满足j倍构成i,则game over
{
flag = 1;
break;
}
}
}
if(flag) puts("Tom");
else puts("Jerry");
}
return 0;
}