外卖店优先级
时间限制: 1.0s 内存限制: 256.0MB 本题总分:20 分
【问题描述】
“饱了么”外卖系统中维护着 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
【样例解释】
6 时刻时,1 号店优先级降到 3,被移除出优先缓存;2 号店优先级升到 6, 加入优先缓存。所以是有 1 家店 (2 号) 在优先缓存中。
【评测用例规模与约定】
对于 80% 的评测用例,1 ≤ N, M, T ≤ 10000。
对于所有评测用例,1 ≤ N, M, T ≤ 100000,1 ≤ ts ≤ T ,1 ≤ id ≤ N。
解题思路
数据量很大,,,
把每家店接单时间单独存,然后对每家店排序(总耗时不超过O(MlogM)),
然后分别处理每家店,依次枚举一家店的每个单,假设第i家店在1~T时间内共接到3个单,时间分别为 t1,t2,t3,那么优先级就先减去t1-1,如果优先度小于0,置为0(最小为0),然后 +2(接到单t1), 然后依次减去两个单之间的时间差(小于0置零),再次+2。最后减去时间T和最后一单的时间差。 在这个过程里加上对优先级>=5 ,<=3的判断即可。 (总耗时O(M))
所以耗时主要在排序~
Code
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 1e5+5;
vector< int> v[maxn]; //v[i]存第i家店接到单的时间
int main()
{
int n,m,t;
cin >> n >> m >> t;
int t1,t2;
for(int i=1;i<=m;i++) {
cin >> t1 >> t2;
v[t2].push_back(t1);
}
for(int i=1;i<=n;i++)
sort(v[i].begin(),v[i].end());
int tot=0; // 最终优先缓存中的店数
bool flag; // 标记一家店是否在优先缓存中
for(int i=1;i<=n;i++) {
int len = v[i].size();
int pri=0; // 优先级
flag = false;
for(int j=0;j<len;j++) {
if(j == 0)
pri -= (v[i][j]-1);
else
pri -= (v[i][j]-v[i][j-1]-1);
if(pri < 0)
pri = 0;
pri += 2;
if(flag && pri <= 3) //本在优先缓存中,但优先级<=3,移出优先缓存
flag = false;
else if(pri >= 5) // 优先级>=5,插入优先缓存中
flag = true;
}
if(flag) {
pri -= (t-v[i][len-1]);
if(pri <= 3)
flag = false;
}
if(flag)
tot++;
}
cout << tot << endl;
}