AcWing 1238. 日志统计
小明维护着一个程序员论坛。现在他收集了一份”点赞”日志,日志共有 N
行。
其中每一行的格式是:
ts id
表示在 ts
时刻编号 id
的帖子收到一个”赞”。
现在小明想统计有哪些帖子曾经是”热帖”。
如果一个帖子曾在任意一个长度为 D
的时间段内收到不少于 K
个赞,小明就认为这个帖子曾是”热帖”。
具体来说,如果存在某个时刻 T
满足该帖在 [T,T+D) 这段时间内(注意是左闭右开区间)收到不少于 K
个赞,该帖就曾是”热帖”。
给定日志,请你帮助小明统计出所有曾是”热帖”的帖子编号。
输入格式
第一行包含三个整数 N,D,K
。
以下 N
行每行一条日志,包含两个整数 ts 和 id
。
输出格式
按从小到大的顺序输出热帖 id
。
每个 id
占一行。
数据范围
1≤K≤N≤105
,
0≤ts,id≤105,
1≤D≤10000
输入样例:
7 10 2
0 1
0 10
10 10
10 1
9 1
100 3
100 3
输出样例:
1
3
思路:很容易想到对日志进行个排序,然后通过滑动窗口统计某个帖子在某段时间内的点赞次数。
代码实现:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef pair<int, int> P;
int n, d, k;
vector<P> arr;
bool cmp(P p1, P p2){
if(p1.second == p2.second){
return p1.first < p2.first;
}
return p1.second < p2.second;
}
int main(){
cin>>n>>d>>k;
int a, b;
for(int i = 0; i < n; i++){
cin>>a>>b;
arr.push_back(P(a, b));
}
sort(arr.begin(), arr.end(), cmp);
// 滑动窗口
int l = 0, r = 0;
while(r < n){
if(arr[r].second == arr[l].second && arr[r].first - arr[l].first < d){
if(r - l + 1 >= k){
cout<<arr[l].second<<endl;
while(arr[r].second == arr[l].second)r++;
l = r;
continue;
}
r++;
}else if(arr[r].second == arr[l].second && arr[r].first - arr[l].first >= d){
l++;
r++;
}else{
l = r;
}
}
return 0;
}