POJ 2379 ACM Rank Table 排序, map

时光总嘲笑我的痴心妄想 提交于 2020-02-04 01:53:07

题目意思:
利用的就是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
*/
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!