思路:
对于第i个管道,若它里面有a个珍珠,我们可以枚举出它可以达到的所有合法状态(就是管道里面的珍珠不能多于N个),并将该管道与该状态建边。然后匈牙利跑一次最大匹配,看匹配值是不是N即可。(因为共有N个状态,当N个管道全部匹配的时候,说明它们匹配的状态全都不一样,这样可以说明这个时候N个状态全部达到了)
以4 3 1 1 2 3为样例。
1 可以变成 {1,4}
1 可以变成 {1,4}
2 可以变成{2}
3 可以变成{3}
如果从集合{1,1,2,3}到集合{1,2,3,4}的最大匹配数为N,则代表这两两匹配,Jerry胜出,否则Tom胜出。
#include
#include
#include
#include
#include
#include
#define maxn 200
using namespace std;
int map[maxn][maxn];
int link[maxn];
int used[maxn];
int n, k;
int dfs(int x){
for(int i = 1; i <= n; ++i){
if(map[x][i] && !used[i]){
used[i] = 1;
if(link[i] == -1 || dfs(link[i])){
link[i] = x;
return true;
}
}
}
return false;
}
int hungary(){
int ans = 0;
memset(link, -1, sizeof(link));
for(int j = 1; j <= n; ++j){
memset(used, 0, sizeof(used));
if(dfs(j))
ans++;
}
return ans;
}
int main (){
int T;
int num;
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &k);
memset(map,0,sizeof(map));
for(int i = 1; i <= n; ++i){
scanf("%d", &num);
while(num <= n){
map[num][i] = 1;
num += k;
}
}
int sum = hungary();
if(sum == n)
printf("Jerry\n");
else
printf("Tom\n");
}
return 0;
}