PAT(甲级)2020年春季考试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.

思路

这题也不难,先用二维数组把n人m回合出的数记录下来,再逐回合遍历。设置一个player数组,如果这个人出局了那么就设为false。遍历时只考虑player为true的人。然后就是判断出的数是否符合条件判断可以分为两部分:这个数是否出现;这个数是不是曾经出现的两个数的差。最后遍历player数组,把没出局的人push到vector里,如果大家都出局了(v为空)就输出没有获胜者。我本想用set存储已有的数,但是后来觉得有一些不方便就换成了vector+sort,结果有一个4分的点超时。看了其他人的题解,发现用unordered_set存储就可以了,又学到一招!判断当前值是否出现在集合里这样做太妙啦~~

踩坑点:以前我一直以为初始化时,bool player[11]={true}就是把player里面的所有元素都赋值了true。但是结果总是不对,经过测试,发现只有player[0]被成功赋值成了true。这个误区以前还从来没发现,以后一定记得全部赋值要用fill!!!

我的代码

#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
int n,m,cnt=0,s[10005],num[11][1005];
vector<int> v;
bool player[11];
bool find(int t){
	for(int i=0;i<cnt;i++){
		if(s[i]==t) return false;
		for(int j=i+1;j<cnt;j++){
			if(s[j]==t) return false;
			if(s[j]-s[i]==t){
				s[cnt++]=t;
				return true;
			}else if(s[j]-s[i]>t)
				break;
		}
	}
	return false;
}
int main(){
	fill(player,player+11,true);
	int t1,t2;
	scanf("%d%d",&t1,&t2);
	s[cnt++]=t1;
	s[cnt++]=t2;
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			scanf("%d",&num[i][j]);
		}
	}
	for(int i=0;i<m;i++){
		for(int j=0;j<n;j++){
			if(player[j]==true){
				t1=num[j][i];
				sort(s,s+cnt);
				if(!find(t1)){
					printf("Round #%d: %d is out.\n",i+1,j+1);
					player[j]=false;
				}
			}
		}
	}
	for(int i=0;i<n;i++){
		if(player[i]==true)
			v.push_back(i);	
	}
	if(v.empty()) printf("No winner.");
	else{
		printf("Winner(s):");
		for(int i=0;i<v.size();i++)
			printf(" %d",v[i]+1);
	}
	return 0;
}

AC代码 

#include<iostream>
#include<cmath>
#include<unordered_set>
using namespace std;
unordered_set<int> s,oid;
int a[15][1005];
bool jugde(int x){
    unordered_set<int>::iterator it=s.begin();
    for(;it!=s.end();it++){
        if(s.find((*it)+x)!=s.end())
            return true;
    }
    return false;
}
int main(){
    int q,p,n,m;
    cin>>q>>p>>n>>m;
    s.insert(q);s.insert(p);
    bool f=true;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            scanf("%d",&a[i][j]);
        }
    }
    for(int j=0;j<m;j++){
        for(int i=0;i<n;i++){
            if(oid.find(i)!=oid.end())continue;
            int x=a[i][j];
            if(s.find(x)!=s.end() || !jugde(x)){
                oid.insert(i);
                printf("Round #%d: %d is out.\n",j+1,i+1);
            }else{
                s.insert(x);
            }
 
        }
    }
    bool flag=false;
    for(int i=0;i<n;i++){
        if(oid.find(i)==oid.end()){
            if(!flag){
                flag=true;
                printf("Winner(s): %d",i+1);
            }else printf(" %d",i+1);
        }
    }
    if(!flag)printf("No winner.");
 
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值