2016NOIp普及組——海港——模擬
題目來源
題目描述
小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
樣例解釋
【樣例解釋1】
第一艘船在第1秒到達海港,最近24小時到達的船是第一艘船,共有4個乘客, 分別是來自國家4,1,2,2,共來自3個不同的國家;
第二艘船在第2秒到達海港,最近24小時到達的船是第一艘船和第二艘船,共有 4 + 2 = 6個乘客,分別是來自國家4,1,2,2,2,3,共來自4個不同的國家;
第三艘船在第10秒到達海港,最近24小時到達的船是第一艘船、第二艘船和第 三艘船,共有4+ 2+1=7個乘客,分別是來自國家4,1,2,2,2,3,3,共來自4個不同 的國家。
【樣例解釋2】
第一艘船在第1秒到達海港,最近24小時到達的船是第一艘船,共有4個乘客,分別是來自國家1,2,2,3,共來自3個不同的國家。
第二艘船在第3秒到達海港,最近24小時到達的船是第一艘船和第二艘船,共有4+2=6個乘客,分別是來自國家1,2,2,3,2,3,共來自3個不同的國家。
第三艘船在第86401秒到達海港,最近24小時到達的船是第二艘船和第三艘船,共有2+2=4個乘客,分別是來自國家2,3,3,4,共來自3個不同的國家。
第四艘船在第86402秒到達海港,最近24小時到達的船是第二艘船、第三艘船和第四艘船,共有2+2+1=5個乘客,分別是來自國家2,3,3,4,5,共來自4個不同的國家。
解題思路
- 本題使用隊列進行模擬
- 對每個到達的船隻進行如下操作:
- 判斷隊首船隻的時間與當前到達船隻的時間是否相差超過 24h。如果相差超過了 24h,那麼隊首的船隻對當前船隻及其之後的所有船隻的國籍統計來說沒有任何用處了,因此就對隊首元素出隊
- 維護一個 f[] 數組和 ans 變量,f[i] 表示的是當前隊國籍爲 i 的人數,ans變量表示的是當前存在的不同國籍的個數
- 那麼在入隊和出隊時就要更改 f[] 數組和 i 變量的值
- 對每一個入隊操作進行如下判斷:
- 更新相應的 f[i] 值
- 如果 f[i] 從 0 增加爲 1 說明出現了一個新的國家,因此更新ans的值
- 對每一個出隊操作進行如下判斷:
- 更新相應的 f[i] 值
- 如果 f[i] 從 1 減小爲 0 說明有一個國家超出了統計範圍,因此更新ans的值
源代碼
#include<queue>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n;
struct da{
int t;
int n;
int a[105];
}data[100005];
int flg[100005];
queue <da> lie;
int ans = 0;
void push(da data){
lie.push(data);
for(int i = 1;i <= data.n;i++){
if(flg[data.a[i]] == 0){
ans ++;
}
flg[data.a[i]]++;
}
}
void pop(){
da a = lie.front();
lie.pop();
for(int i = 1;i <= a.n;i++){
flg[a.a[i]]--;
if(flg[a.a[i]] == 0){
ans--;
}
}
}
int main(){
scanf("%d",&n);
for(int i = 1;i <= n;i++){
scanf("%d%d",&data[i].t,&data[i].n);
for(int x = 1;x <= data[i].n;x++){
scanf("%d",&data[i].a[x]);
}
push(data[i]);
da a = lie.front();
while(a.t + 86400 <= data[i].t){
pop();
a = lie.front();
}
a = data[i];
cout << ans << endl;
}
}