题目意思:
利用的就是acm的竞赛排名规则。大意是队伍参见比赛,然后让我们计算排名,第一关键词是过题数,过题数越多的队伍排名越高,排名相同的队伍看第二关键词时间,时间越短的队伍排名越高。
每道题目提交失败还会罚时,但是要注意的是若不通过题目,是不计算罚时的。
/*
本题要点:
1、 每道题都有第一次AC 的时间(秒做单位), 假设为 t1 = 3000, 这道题之前会可能错了很多次, 每错一次, 罚时 1200 秒。假如错三次
罚时 t2 = 1200 * 3;
每道题所花的时间为 t1 + t2 = 3000 + 3600 = 6600 ;
每个队伍,一共 AC 了几道题,算上这些题的所有时间,得到总时间
2、 队伍AC后可能还提交,无论对还是错,时间都是不算的
3、 数据输入的顺序是不一定的,也就是说两次AC,但是后面AC时间是最靠前的,这时后来提交的AC时间要忽略
4、 最后排序是AC->Time->id来排序的
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
typedef pair<int, int> PII; // 记录 <团队编号, 题目编号>
map<PII, int> min_ac_time; // <团队编号, 题目编号> 到该题 AC 的最早时间
map<PII, int> wa_times; // <团队编号, 题目编号> 所对应的 错误次数
const int MaxN = 1010;
int c, n;
struct Run // 提交
{
int team_id, p_id, time;
int ac;
}runs[MaxN];
struct Team //队伍
{
int team_id, ac_cnt, total_ti;
bool operator<(const Team& rhs) const
{
if(ac_cnt != rhs.ac_cnt)
{
return ac_cnt > rhs.ac_cnt;
}else{
if(total_ti != rhs.total_ti)
{
return total_ti < rhs.total_ti;
}else{
return team_id < rhs.team_id;
}
}
}
}teams[MaxN];
int main()
{
scanf("%d%d", &c, &n);
for(int i = 1; i <= c; ++i)
{
teams[i].team_id = i;
teams[i].total_ti = 0;
}
for(int i = 0; i < n; ++i)
{
scanf("%d%d%d%d", &runs[i].team_id, &runs[i].p_id, &runs[i].time, &runs[i].ac);
if(runs[i].ac)
{
PII p = make_pair(runs[i].team_id, runs[i].p_id);
map<PII, int>::iterator it = min_ac_time.find(p);
if(it == min_ac_time.end() || it->second > runs[i].time)
{
min_ac_time[p] = runs[i].time; // 对应每一道题,找到该 team 的最早 AC 时间
}
}
}
for(int i = 0; i < n; ++i)
{
if(0 == runs[i].ac)
{
PII p = make_pair(runs[i].team_id, runs[i].p_id);
map<PII, int>::iterator it = min_ac_time.find(p);
if(it != min_ac_time.end() && it->second > runs[i].time)
{
wa_times[p]++; // 错误次数 加 1
}
}
}
map<PII, int>::iterator it = min_ac_time.begin();
while(it != min_ac_time.end())
{
int team_id, total_ti;
team_id = it->first.first;
total_ti = it->second;
teams[team_id].ac_cnt++;
teams[team_id].total_ti += total_ti; //所有的提交时间加起来
++it;
}
it = wa_times.begin();
while(it != wa_times.end())
{
int id = it->first.first;
teams[id].total_ti += 1200 * it->second; //罚时, 每一次罚时 1200 秒
++it;
}
sort(teams + 1, teams + c + 1); // 队伍的编号从 1 开始
printf("%d", teams[1].team_id);
for(int i = 2; i <= c; ++i)
{
printf(" %d", teams[i].team_id);
}
printf("\n");
return 0;
}
/*
3 3
1 2 3000 0
1 2 3100 1
2 1 4200 1
*/
/*
2 1 3
*/
来源:CSDN
作者:qq_38232157
链接:https://blog.csdn.net/qq_38232157/article/details/104156228