2017-2018 ACM-ICPC Nordic ——Problem G 。Galactic Collegiate Programming Contest

Time limit: 6 

secondsPicture by GuillaumePreat on Pixabay, cc0One hundred years from now, in 2117, the InternationalCollegiate Programming Contest(of which the NCPC is a part) has expandedsignificantly and it is now the Galactic CollegiateProgramming Contest (GCPC).This year there are n teams in the contest.The teams are numbered 1, 2, . . . , n, and yourfavorite team has number 1.Like today, the score of a team is a pair ofintegers (a, b) where a is the number of solvedproblems and b is the total penalty of that team.When a team solves a problem there is some associated penalty (not necessarily calculated inthe same way as in the NCPC – the precise details are not important in this problem). The totalpenalty of a team is the sum of the penalties for the solved problems of the team.Consider two teams t1 and t2 whose scores are (a1, b1) and (a2, b2). The score of team t1 isbetter than that of t2 if either a1 > a2, or if a1 = a2 and b1 < b2. The rank of a team is k + 1where k is the number of teams whose score is better.You would like to follow the performance of your favorite team. Unfortunately, the organizersof GCPC do not provide a scoreboard. Instead, they send a message immediately whenever ateam solves a problem.InputThe first line of input contains two integers n and m, where 1 ≤ n ≤ 105is the number of teams,and 1 ≤ m ≤ 105is the number of events.Then follow m lines that describe the events. Each line contains two integers t and p(1 ≤ t ≤ n and 1 ≤ p ≤ 1000), meaning that team t has solved a problem with penalty p. Theevents are ordered by the time when they happen.OutputOutput m lines. On the i’th line, output the rank of your favorite team after the first i eventshave happened.

Sample Input 1

3 4

2 7

3 5

1 6

1 9

 Sample Output 1

2

3

2

1


题意:给你一个n,一个m;表示有1~n个队伍参加比赛,一共有m道题;给你每道题的回答结果x y,表示第i道题由x队回答正确,则x队的答题数a + 1,但是罚时b+y;

最初每队都是(0,0),根据每题的答题结果,对1~n对进行rank排序,每答出一道题访问一下1队的rank排名,输出;


分析:一开始写了个while() + sort()的,因为觉得6秒不会出现超时结果,倒是还是超时了,低估了自己的时间复杂度;

后来比赛结束去问了安阿姨才知道用队列统计rank在我前面的人就好;然后想到结构体+队列;但是发现当队列里的队伍过题之后我无法更新,就换成队列里放队伍的标号,在开两个数组分别放a 和 b;这样不会难以更新;

当别人过题了,你只需要判断别人的成绩输不是比自己好就行,好就加到队列里,但是这是你需要判断在之前该队是否已经在队列里,所以你需要一个VIS数组标记一下该队是否在队列里;

当自己过题时a+1,b+y;扫一遍队列,看看这是比自己成绩好的还有哪些;这个操作就是把队列里的队伍都pop出来在判断是否比自己好,比自己好就重新加入队列,否者推出;(你自己过题之后只用考虑之前比自己好的人就好,就是指队列里的);




AC码:

#include <bits/stdc++.h>

typedef long long LL;
using namespace std;
const int Manx = 1e5;


queue <int> que;
int vis[Manx + 1];
int a[Manx + 1], b[Manx + 1];

int main()
{
	int n, m;
	scanf("%d %d",&n, &m);
	int ans = 1;
	int len = 0;
	while(m--)
	{
		int x, y;
		scanf("%d %d",&x,&y);
		if(x != 1)
		{
			a[x] ++;
			b[x] += y;
			if(a[x] > a[1] || (a[x] == a[1] && b[x] < b[1]))
			{
				if(vis[x] == 0)
				{
					que.push(x);
					vis[x] = 1;
				}
			}
		}
		else if(x == 1)
		{
			a[1] ++;
			b[1] += y;
			len = que.size();
			for(int i = 1;i <= len;i++)
			{
				int nod = que.front();
				que.pop();
				if(a[nod] > a[1] || (a[nod] == a[1] && b[nod] < b[1]))
				{
					que.push(nod);
				}
				else vis[nod] = 0; 
			}
		}
		len = que.size();
		ans = len + 1;
		printf("%d\n",ans);
	}
	return 0;


猜你喜欢

转载自blog.csdn.net/strawberry_595/article/details/80358335