1. 程式人生 > >2017-2018 ACM-ICPC Nordic ——Problem G 。Galactic Collegiate Programming Contest

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;
 <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;