1.预备知识:queue<结构体> q
使用STL定义一个队列时,不使用常规数据类型,而是使用结构体,因为每一次入队不只是添加一个数据,而要一组数据打包成一个位置添加进去。通常有两种方法。
(1)
struct node
{
int x,y;
};
queue<node> q;
//入队
cin>>a>>b;
q.push({a,b});
(2)更推荐
struct node
{
int x,y;
}p;
queue<node> q;
//入队
cin>>a>>b;
p.x=a,p.y=b;
q.push(p);
2.本题思路
1)最开始的思路是这样的:开一个book数组,每次一个人入队,book[该人国籍]=1,但这会遇到一个问题,当一个人超出时间而要出队时,并不能book[该人国籍]=0,因为在队列里可能还有和他相同国籍的人,而这些人还在时限内不需要出队列。那么该如何解决呢,这里用到了常用的去重方法(这个问题的本质是判断这个国籍的人有没有重复):通过桶排序的思想,即计数排序,来解决问题。
2)如何优化
仔细思考船进入海港后统计船上的人,实际上船的批次对这个问题没有任何影响,真正起作用的是人,因此可以开一个结构体,记录每个人到达的时间和他的国籍,每次入队只需要把这个人传进去就可以了,因此就简化掉了船这个因素。
3)代码实现
只需要开一个数组记录每个国籍人数,ct[100005] ,ct为country简写
入队:若入队前ct[该人国籍]==0,答案数加1。不为零,答案不变。
出队:若出队后ct[该人国籍]==0,答案数减1。不为零,答案不变。
3.代码
#include<iostream>
#include<queue>
using namespace std;
struct people
{
int t,x;
}p;
int n,t,k,tmp,ans,ct[100005];
int main()
{
int i,j;
queue<people> q;
cin>>n;
for (i=1;i<=n;i++)
{
people p;
cin>>t>>k;
for (j=1;j<=k;j++)
{
cin>>tmp;
if (ct[tmp]==0) ans++;
ct[tmp]++;
p.t=t,p.x=tmp;
q.push(p);
}
p=q.front();
while (t-p.t>=86400)
{
q.pop();
ct[p.x]--;
if (ct[p.x]==0)
ans--;
p=q.front();
}
cout<<ans<<endl;
}
return 0;
}