【PAT甲级2020年春季考试】7-2 The Judger (25分)(c++)

7-2 The Judger (25分)

A game of numbers has the following rules: at the beginning, two distinct positive integers are given by the judge. Then each player in turn must give a number to the judge. The number must be the difference of two numbers that are previously given, and must not be duplicated to any of the existed numbers. The game will run for several rounds. The one who gives a duplicate number or even a wrong number will be kicked out.

Your job is to write a judger program to judge the players’ numbers and to determine the final winners.

Input Specification:
Each input file contains one test case. For each case, the first line gives two distinct positive integers to begin with. Both numbers are in [1,10​5].

In the second line, two numbers are given: N (2≤N≤10), the number of players, and M (2≤M≤10​3), the number of rounds.

Then N lines follow, each contains M positive integers. The i-th line corresponds to the i-th player (i=1,⋯,N). The game is to start from the 1st player giving his/her 1st number, followed by everybody else giving their 1st numbers in the 1st round; then everyone give their 2nd numbers in the 2nd round, and so on so forth.

Output Specification:
If the i-th player is kicked out in the k-th round, print in a line Round #k: i is out… The rest of the numbers given by the one who is out of the game will be ignored. If more than one player is out in the same round, print them in increasing order of their indices. When the game is over, print in the last line Winner(s): W1 W2 … Wn, where W1 … Wn are the indices of the winners in increasing order. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the beginning or the end of the line. If there is no winner, print No winner. instead.

Sample Input 1:

101 42
4 5
59 34 67 9 7
17 9 8 50 7
25 92 43 26 37
76 51 1 41 40

Sample Output 1:

Round #4: 1 is out.
Round #5: 3 is out.
Winner(s): 2 4

Sample Input 2:

42 101
4 5
59 34 67 9 7
17 9 18 50 49
25 92 58 1 39
102 32 2 6 41
Sample Output 2:
Round #1: 4 is out.
Round #3: 2 is out.
Round #4: 1 is out.
Round #5: 3 is out.
No winner.

题意:

给两个正整数放入大集合(一开始就两数),所有人依次给出大集合中任意两个数的差,若玩家给出的数在大集合中出现过或者是大集合中作差得不到的数,那么该玩家淘汰,忽略他当前和之后所有写的数,若符合要求,那么他写的数加入大集合中。游戏一轮一轮进行,每轮有玩家淘汰就输出。

思路:

用一个哈希表来记录写的数是否在大集合中出现过,再用一个哈希表记录所有作差能得到的数,这里有个窍门,我们只要计算两两之间差的绝对值,那么只要每插入一个数,就计算这个数与原先每个数的差(因为其他数的差已经统计好了,哈希表已经记录下来了),再用哈希表记录。
然后坑点,一轮有多个玩家淘汰时,不能将玩家序列号像赢家那样放在一起输出,注意到is out只能一个一个淘汰,所以要分多列输出。

参考代码:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
int hash1[100000] = {0};
bool hash2[100000] = {false};

int main() {
    vector<int> a(2), win;
    int n, m, num;
    scanf("%d%d%d%d", &a[0], &a[1], &n, &m);
    hash1[a[0]] = 1;
    hash1[a[1]] = 1;
    vector<int> v[n], flag(n, 0);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            scanf("%d", &num);
            v[i].push_back(num);
        }
    }
    for (int j = 0; j < m; j++) {
        vector<int> out;
        for (int i = 0; i < n; i++) {
            if (flag[i])continue;
            for (int k = a.size() - 2; k >= 0; k--)
                hash2[abs(a[a.size() - 1] - a[k])] = true;
            if (hash1[v[i][j]] == 0 && hash2[v[i][j]]) {
                a.push_back(v[i][j]);
                hash1[v[i][j]] = 1;
            } else {
                flag[i] = true;
                out.push_back(i + 1);
            }
        }
        if (!out.empty()) {
            for (int k = 0; k < out.size(); k++)
                printf("Round #%d: %d is out.\n", j + 1, out[k]);
        }
    }
    for (int i = 0; i < n; i++)
        if (!flag[i])win.push_back(i + 1);
    if (win.empty())printf("No winner.");
    else {
        printf("Winner(s):");
        for (int i = 0; i < win.size(); i++)printf(" %d", win[i]);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值