1. 程式人生 > >NOIP 2016 PJ T3 海港

NOIP 2016 PJ T3 海港

P2058 海港

題目描述

小K是一個海港的海關工作人員,每天都有許多船隻到達海港,船上通常有很多來自不同國家的乘客。

小K對這些到達海港的船隻非常感興趣,他按照時間記錄下了到達海港的每一艘船隻情況;對於第i艘到達的船,他記錄了這艘船到達的時間ti (單位:秒),船上的乘 客數星ki,以及每名乘客的國籍 x(i,1), x(i,2),…,x(i,k);。

小K統計了n艘船的資訊,希望你幫忙計算出以每一艘船到達時間為止的24小時(24小時=86400秒)內所有乘船到達的乘客來自多少個不同的國家。

形式化地講,你需要計算n條資訊。對於輸出的第i條資訊,你需要統計滿足 ti - 86400 < tp <= ti的船隻p,在所有的x(p,j)中,總共有多少個不同的數。

輸入輸出格式

輸入格式:

第一行輸入一個正整數n,表示小K統計了 n艘船的資訊。

接下來n行,每行描述一艘船的資訊:前兩個整數ti和ki分別表示這艘船到達海港的時間和船上的乘客數量,接下來ki個整數x(i,j)表示船上乘客的國7。

保證輸入的ti是遞增的,單位是秒;表示從小K第一次上班開始計時,這艘船在第 ti 秒到達海港。

保證  ,, 

其中表示所有的ki的和。

輸出格式:

輸出n行,第i行輸出一個整數表示第i艘船到達後的統計資訊。

輸入輸出樣例

輸入樣例#1:

3
1 4 4 1 2 2
2 2 2 3
10 1 3

輸出樣例#1:

3
4
4

輸入樣例#2:

4
1 4 1 2 2 3
3 2 2 3
86401 2 3 4
86402 1 5

輸出樣例#2:

3
3
3
4

剛開始爆搜,顯然會RE。最後總結出來用動態陣列或佇列。(當時就怎麼沒想到呢555MLGB)。

我選擇用佇列,只要判斷一下加進來的時間有沒有和隊首的時間相差86400s,如果超過了,就把之前的那艘船上的人的國家--,在pop掉就行了。但是這一有一個問題:

佇列中是存人還是存船呢?當然是存人,不然還要給每艘船一個數組來存人的國家,會TLE的。

程式碼如下:

#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<queue>
using namespace std;
int x[100005],n,sum,g;
struct node
{
	int t,p;//分別代表每個人的時間和國家
	node(){}
	node(int a,int b){//定義一個函式來push
		t=a,p=b;
	}
};
queue <node> h;

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		int t,p;
		scanf("%d%d",&t,&p);
		for(int j=1;j<=p;j++){
			scanf("%d",&g);
			h.push(node(t,g));//push時間和國家
			x[g]++;//那個國家的人++
			if(x[g]==1) sum++;//如果這個人來後僅僅才1個人,那麼之前是沒有這個
		}                                                 //的人的,所以要把sum++
		while(h.front().t<=t-86400)//如果首位相差86400s就進行pop
		{
			x[h.front().p]--;if(x[h.front().p]==0) sum--;//同理,如果這個人走
			h.pop();                            //後這個國家沒人了,就要sum--
		}
		printf("%d\n",sum);
	}
}