2020pat 春季2、4题解

第二题:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
题意:由裁判先给出两个数,然后各个选手依次给出一个数,这个数要是之前所给的任意两个数的差而且不能重复给出,否则出局,出局的人下次所给的数字忽略。
分析:首先用一个二维数组来存储输入的数字,用一个名为num的set来保存每个选手所给的数,每次将所给的数x与num中的每个数相加来查找两个数的和是否在num中,在则说明x是这两个数的差,否则放入wrong的set中,表示这个选手出局。同时打印出局信息,下一次再输入该选手的信息,如果wrong中有该选手,则跳过。同时用vis标记哪些不在wrong中的选手,方便输出。

#include<iostream>
#include<unordered_set>
#include<vector>
#include<algorithm>
using namespace std;
int input[15][1010];
unordered_set<int> num, wrong, win;
bool vis[15];
bool judge(int x)
{
    
    
	for(auto it = num.begin(); it != num.end(); it++)
	{
    
    
		if(num.find(*it+x) != num.end())
		return true;
	}
	return false;
}
int main()
{
    
    
	int a, b, n, m;
	scanf("%d%d%d%d", &a, &b, &n, &m);
	for(int i = 1; i <= n; i++)
	{
    
    
		for(int j = 1; j <= m; j++)
		scanf("%d", &input[i][j]);
	}
	num.insert(a), num.insert(b);
	for(int j = 1; j <= m; j++)
	{
    
    
		for(int i = 1; i <= n; i++)
		{
    
    
			if(wrong.find(i) != wrong.end())
			continue;
			if(num.find(input[i][j]) != num.end() || judge(input[i][j]) == false)
			{
    
    
				wrong.insert(i);
				vis[i] = true;
				printf("Round #%d: %d is out.\n", j, i);
			}
			else
			{
    
    
				num.insert(input[i][j]);
				win.insert(i);
			}
		}
	}
	int cnt = 0;
	vector<int> w;
	for(auto it = win.begin(); it != win.end(); it++)
	if(vis[*it] == false)
	w.push_back(*it);
	
	if(w.size() == 0)
	{
    
    
		printf("No winner.\n");
		return 0;
	}
	else
	{
    
    
        sort(w.begin(), w.end());
		printf("Winner(s):");
		for(auto i: w)
		printf(" %d", i);
	}
 } 

第四题:
在这里插入图片描述
在这里插入图片描述
用优先队列来模拟。

#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 1e5+10;
priority_queue<int, vector<int>, greater<int> > q;
int num[maxn];
vector<int> ans[maxn];
int lev = 0;
int main()
{
    
    
	int n, m;
	scanf("%d%d", &n, &m);
	for(int i = 0; i < n; i++)
	scanf("%d", &num[i]);
	for(int i = 0; i < m; i++)
	q.push(num[i]);
	for(int i = m; i < n; i++)
	{
    
    
		if(q.empty())//如果当前队列为空,就把下一轮的数据全部放入队列中,同时清空下一轮,方便下一次使用。
		{
    
    
			for(int e: ans[lev+1])
			q.push(e);
			ans[lev+1].clear();
			lev++;
		 } 
		int top = q.top();
		if(top < num[i])//如果放入的数据大于输出的数据,就把输出的数据放在当前一轮要输出的容器中,然后将要输入的数据放入队列q中,同时将队首的数据输出。
		{
    
    
			ans[lev].push_back(top);
			q.pop();
			q.push(num[i]);
		}
		else//如果放入的数据小于输出的数据,就把输出的数据放在当前一轮要输出的容器中,输入的数据放在下一轮要输出的容器中,同时将队首的数据输出。
		{
    
    
			ans[lev].push_back(top);
			q.pop();
			ans[lev+1].push_back(num[i]);
		}
	}
	while(!q.empty())
	{
    
    
		ans[lev].push_back(q.top());
		q.pop();
	}//检查有没有未放完的数据。
	for(int i = 0; i <= lev+1; i++)//i<=lev+1是因为可能下一轮还有数据。
	{
    
    
		if(i >= lev && ans[i].size()== 0)//如果当前轮已经空了下一轮就一定没有数据了,所以可以提前退出。
		break;
		sort(ans[i].begin(), ans[i].end());
		for(int j = 0; j < ans[i].size(); j++)
		printf("%d%c", ans[i][j], j < ans[i].size()-1 ? ' ' : '\n');
	}
 } 

猜你喜欢

转载自blog.csdn.net/weixin_45486992/article/details/108347418