题目描述
“饱了么”外卖系统中维护着 N 家外卖店,编号 1 ∼ N。每家外卖店都有 一个优先级,初始时 (0 时刻) 优先级都为 0。
每经过 1 个时间单位,如果外卖店没有订单,则优先级会减少 1,最低减 到 0;而如果外卖店有订单,则优先级不减反加,每有一单优先级加 2。
如果某家外卖店某时刻优先级大于 5,则会被系统加入优先缓存中;如果 优先级小于等于 3,则会被清除出优先缓存。
给定 T 时刻以内的 M 条订单信息,请你计算 T 时刻时有多少外卖店在优 先缓存中。
输入
第一行包含 3 个整数 N、M 和 T。
以下 M 行每行包含两个整数 ts 和 id,表示 ts 时刻编号 id 的外卖店收到
一个订单。
输出
输出一个整数代表答案。
样例输入
2 6 6
1 1
5 2
3 1
6 2
2 1
6 2
样例输出
1
提示
对于 80% 的评测用例,1 ≤ N, M, T ≤ 10000。 对于所有评测用例,1 ≤ N,M,T ≤ 100000,1 ≤ ts ≤ T,1 ≤ id ≤ N。
思路:一开始想复杂了,本来想用线段树区间操作的,但是线段树没有办法记录中间某一状态。它只可以知道最终的结果,但是没有办法求得中间某一时刻大于5但是后来小于5大于等于3的数量,所以线段树不行。其实我们可以对每一个外卖店进行求解,因为外卖店是相互不影响的,因此我们对每一个外卖店按照题意模拟就可以了。。淦
代码如下:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxx=1e5+100;
vector<int> p[maxx];
int vis[maxx];
int n,m,t;
int main()
{
scanf("%d%d%d",&n,&m,&t);
for(int i=1;i<=n;i++) p[i].clear();
int x,y;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
p[y].push_back(x);
}
int ans=0;
for(int i=1;i<=n;i++)
{
sort(p[i].begin(),p[i].end());
int num=0;
for(int j=0;j<p[i].size();j++)
{
if(j==0) num+=2;
else
{
if(p[i][j]!=p[i][j-1]) num-=(p[i][j]-p[i][j-1]-1);
if(num<0) num=0;
if(num<=3) vis[i]=0;
num+=2;
}
if(num>5) vis[i]=1;
}
if(p[i].size())num-=(t-p[i][p[i].size()-1]);
if(num<=3) vis[i]=0;
if(vis[i]==1) ans++;
}
cout<<ans<<endl;
return 0;
}
努力加油a啊,(o)/~