Game with Pearls(珍珠游戏)

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”.

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”.

/*

Tom和Jerry做游戏,给定N个管子,每个管子上面有一定数目的珍珠。

现在 Jerry 先开始在管子上面再放一些珍珠
放上的珍珠数必须是K的倍数,或者是 0

最后将管子排序,如果可以做到第 i 个管子上面有 i 个珍珠,

则Jerry胜出,反之Tom胜出

解题思路:

贪心算法

将个管子按管子中的珍珠数量升序排序,则满足条件的时候第i个管子应该有i个珍珠。

每个管子开始遍历,如果第i个管子有i个珍珠,则进行下一次循环;

如果大于i个珍珠,则说明不满足条件 

如果小于i个珍珠,则加上k个珍珠,重新按升序排序
(这里一定要重新排序,当你加上 k 之后,a[i] 有可能是 i 之后的某一个个管子里的珍珠数

例如:5 2    1 2 3 3 4

当 i=4 时,a[i]=3, a[i]=a[i]+k=5,  排序之后 ,5 正好是 i=5 时 的珍珠数,而 i=5 时珍珠数 4 恰好是 a[4] 的珍珠数 )
*/
代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    int m,n,k,i,b,flag=0,sum=0;
    int a[101];
    cin>>m;
    while(m--)
    {
        flag=0;
        sum=0;
        memset(a,0,sizeof(a));
        cin>>n>>k;
        for(i=0;i<=n-1;i++)
            scanf("%d",&a[i]);
        sort(a,a+n);
        for(i=0;i<=n-1;i++){
            if(a[i]==i+1){
                sum++;
                continue;
            }
            while(a[i]<i+1){
                a[i]+=k;
                sort(a+i,a+n);
            }
            if(a[i]>i+1){
                flag=1;
                break;
            }
        }
        if(sum==n){
            printf("Jerry\n");
            continue;
        }
        if(flag==1)
            printf("Tom\n");
        else
            printf("Jerry\n");
    }
}
/*
我的错误思路  po 出来长个教训
1 处:
这样是错误的,当 a[i] < k 时,b 为 两者的差,如果直接判断 差是不是 k 的倍数,太过果断了,因为很有可能 a[i]+k 和以后某一项的珍珠数互换就能实现 JERRY 赢(例如正确代码中的例子)
*/
错误的代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    int m,n,k,i,b,flag=0,sum=0;
    int a[101];
    cin>>m;
    while(m--)
    {
        flag=0;
        sum=0;
        memset(a,0,sizeof(a));
        cin>>n>>k;
        for(i=0;i<=n-1;i++)
            scanf("%d",&a[i]);
        sort(a,a+n);
        for(i=0;i<=n-1;i++){
            if(a[i]==i+1){
                sum++;
                continue;
            }
            if(a[i]<i+1){
                b=(i+1)-a[i];
// 1.
                if(b%k==0)
                    flag=1;
                else{
                    flag=0;
                    break;
                }
            }
            if(a[i]>i+1){
                flag=0;
                break;
            }
        }
        if(sum==n||flag==1)
            printf("Jerry\n");
        else
            printf("Tom\n");
    }
}

猜你喜欢

转载自blog.csdn.net/JKdd123456/article/details/80343125