题目
“饱了么”外卖系统中维护着 N 家外卖店,编号 1∼N。每家外卖店都有一个优先级,初始时 (0时刻) 优先级都为 0。每经过 1个时间单位,如果外卖店没有订单,则优先级会减少 1,最低减到 0;而如果外卖店有订单,则优先级不减反加,每有一单优先级加 2。如果某家外卖店某时刻优先级大于 5,则会被系统加入优先缓存中;如果优先级小于等于 3,则会被清除出优先缓存。
给定 T时刻以内的 M 条订单信息,请你计算 T时刻时有多少外卖店在优先缓存中。
输入格式
第一行包含 3个整数 N,M,T。
以下 M行每行包含两个整数 ts 和 id,表示 ts 时刻编号 id的外卖店收到一个订单。
输出格式
输出一个整数代表答案。
数据范围
1≤N,M,T≤105,
1≤ts≤T,
1≤id≤N
输入样例:
2 6 6
1 1
5 2
3 1
6 2
2 1
6 2
输出样例:
1
样例解释
6时刻时,1 号店优先级降到 3,被移除出优先缓存;2 号店优先级升到 6,加入优先缓存。所以是有 1
家店 (2 号) 在优先缓存中。
分析
这个题困扰我的是:如果小于等于3会被清除优先缓存,如果大于5会进入优先缓存,如果一个店原来是5,但是过了一分钟没有订单就会变成4,但是他还是在优先缓存中的,还有一个是同一分钟中,一个店可以有很多订单,比如第三分钟第四号店会有一大批订单,再一个是如果减到零了就不会再减了,不会变成负数的
搞一个结构体,存储每一个订单的时间和几号店,然后先按照店的编号从小到大排序,然后再按照时间先后排序,store[123456],这个数组存储第id号店的上一次有订单的时间,st[123456],这个数组存储第id号店是不是在优先缓存中,value[123456]这个数组存储第id号店的得分
遍历每一个订单,然后再计算在第id号店有这个订单之前上一个订单的时间然后算出这个店需要减去多少,然后再判断是不是小于0了,如果小于0了就变成0,在判断是不是小于等于3了,如果小于等于3了就把他踢出去,然后再加上这个订单带来的2个得分,如果大于5就加到优先缓存里,最后再遍历每一个店,如果这个店的最后一个订单不是第 t 分钟的就减去最后一个订单的时间到 t 时间之间应该减去的,最后在遍历一下每个店求一共有多少个店在优先缓存中
代码
#include<iostream>
#include<algorithm>
using namespace std;
int store[123456],st[123456],value[123456];
struct node{
int ts,i;
}aa[123456];
bool cmp(node a,node b)
{
if(a.i==b.i) return a.ts<b.ts;
return a.i<b.i;
}
int main()
{
int n,m,t,ans=0;
cin>>n>>m>>t;
for(int i=0;i<m;i++) cin>>aa[i].ts>>aa[i].i;
sort(aa,aa+m,cmp);
for(int i=0;i<m;i++)
{
int tt=aa[i].ts,id=aa[i].i;
if(tt!=store[id]) value[id]-=tt-store[id]-1;
value[id]=max(0,value[id]);
if(value[id]<=3) st[id]=0;
value[id]+=2;
if(value[id]>5) st[id]=1;
store[id]=tt;
}
for(int i=1;i<=n;i++)
{
if(store[i]<t)
{
value[i]-=t-store[i];
if(value[i]<=3) st[i]=0;
}
}
for(int i=1;i<=n;i++)
if(st[i]) ans++;
cout<<ans<<endl;
return 0;
}