第二题:
题意:由裁判先给出两个数,然后各个选手依次给出一个数,这个数要是之前所给的任意两个数的差而且不能重复给出,否则出局,出局的人下次所给的数字忽略。
分析:首先用一个二维数组来存储输入的数字,用一个名为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');
}
}