Game with Pearls
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1916 Accepted Submission(s): 672
Problem Description
Tom and Jerry are playing a game with tubes and pearls. The rule of the game is:
1) Tom and Jerry come up together with a number K.
2) Tom provides N tubes. Within each tube, there are several pearls. The number of pearls in each tube is at least 1 and at most N.
3) Jerry puts some more pearls into each tube. The number of pearls put into each tube has to be either 0 or a positive multiple of K. After that Jerry organizes these tubes in the order that the first tube has exact one pearl, the 2nd tube has exact 2 pearls, …, the Nth tube has exact N pearls.
4) If Jerry succeeds, he wins the game, otherwise Tom wins.
Write a program to determine who wins the game according to a given N, K and initial number of pearls in each tube. If Tom wins the game, output “Tom”, otherwise, output “Jerry”.
1) Tom and Jerry come up together with a number K.
2) Tom provides N tubes. Within each tube, there are several pearls. The number of pearls in each tube is at least 1 and at most N.
3) Jerry puts some more pearls into each tube. The number of pearls put into each tube has to be either 0 or a positive multiple of K. After that Jerry organizes these tubes in the order that the first tube has exact one pearl, the 2nd tube has exact 2 pearls, …, the Nth tube has exact N pearls.
4) If Jerry succeeds, he wins the game, otherwise Tom wins.
Write a program to determine who wins the game according to a given N, K and initial number of pearls in each tube. If Tom wins the game, output “Tom”, otherwise, output “Jerry”.
Input
The first line contains an integer M (M<=500), then M games follow. For each game, the first line contains 2 integers, N and K (1 <= N <= 100, 1 <= K <= N), and the second line contains N integers presenting the number of pearls in each tube.
Output
For each game, output a line containing either “Tom” or “Jerry”.
Sample Input
2 5 1 1 2 3 4 5 6 2 1 2 3 4 5 5
Sample Output
Jerry Tom
Tom和Jerry做游戏,给定N个管子,每个管子上面有一定数目的珍珠。
现在Jerry开始在管子上面再放一些珍珠,放上的珍珠数必须是K的倍数,可以不放。
最后将管子排序,如果可以做到第i个管子上面有i个珍珠,则Jerry胜出,反之Tom胜出。
思路:
对于第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 <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <iostream>
#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;
}