做题时和其他题混淆了,用了枚举日志的方法,只维护了相邻的两个点赞的信息
acwing外卖店优先级https://www.acwing.com/problem/content/description/1243/
pta银行排队问题之单队列多窗口服务https://pintia.cn/problem-sets/1635264548121292800/exam/problems/1636695635989049353
三者的共同点是题目输入都给了一个时间和id的二元组
且看题干都是要遍历一遍这个二元组的
不同的点是日志统计这个题,给出一个固定的区间,赞的间隔要在这个区间内才算数,右边界更新后,左边的数不能抛弃不管,需要记录在这个区间左右边界的赞的时间,要有个指针指向左边界并且根据右边界的移动而不断移动,恰巧就符合双指针滑动窗口的特征
而外卖店优先级对订单(“赞”)的间隔是没有一个固定的要求的,只需要记录前面的订单(赞)给后面遗留了一个什么样的状态,根据两个相邻订单a,b(“赞”)的时间间隔来更新这个状态,并遗留给下一个订单c(“赞”),遗留过后,a就对后面的订单没有任何影响,可以彻底抛弃不管了
二刷卡壳,最后输出时i的范围写错了,没有走流程对比题干
代码
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; const int N = 1e5 + 10; int t[N]; struct Tiezi{ int ts,id; bool operator<(Tiezi w){ return ts < w.ts; } }tiezi[N]; bool st[N]; int cnt[N]; int main(){ int n,d,k; cin >> n >> d >> k; int ts,id; for(int i= 0;i < n;i++){ cin >> ts >> id; tiezi[i] = {ts,id}; } sort(tiezi,tiezi+n); for(int i = 0,j = 0;j < n;j++){ // 加的是j指针的帖子,所以j要从0开始 int id = tiezi[j].id; int ts = tiezi[j].ts; cnt[id]++; while(ts - tiezi[i].ts >= d){ cnt[tiezi[i].id] -= 1; i++; } if(cnt[id] >= k) st[id] = true; // cout << cnt[1] << endl; } for(int i = 0;i < N;i++){ if(st[i]) cout << i << endl; } return 0; }