题目通道
小明维护着一个程序员论坛。现在他收集了一份”点赞”日志,日志共有 N行。
其中每一行的格式是:
ts id
表示在 ts 时刻编号 id 的帖子收到一个”赞”。
现在小明想统计有哪些帖子曾经是”热帖”。
如果一个帖子曾在任意一个长度为 D 的时间段内收到不少于 K 个赞,小明就认为这个帖子曾是”热帖”。
具体来说,如果存在某个时刻 T满足该帖在 [T,T+D) 这段时间内(注意是左闭右开区间)收到不少于 K个赞,该帖就曾是”热帖”。
给定日志,请你帮助小明统计出所有曾是”热帖”的帖子编号。
输入格式
第一行包含三个整数 N,D,K。
以下 N行每行一条日志,包含两个整数 ts 和 id。
输出格式
按从小到大的顺序输出热帖 id。
每个 id占一行。
数据范围
1≤K≤N≤1e5,
0≤ts,id≤11e5,
1≤D≤10000
输入样例:
7 10 2
0 1
0 10
10 10
10 1
9 1
100 3
100 3
输出样例:
1
3
做题中遇到的题目问题:
1、怎么枚举一个id收到点赞的个数
2、怎么枚举一个时间段,因为时间点没有顺序
3、从小到大的顺序输出热帖 id
问题解析:
1、通过数组cnt[]记录点赞个数,用pair<>进行储存数据
2、将时间段排序
3、循环枚举id
4、通过与k比较决定是否记录ID
用到了双指针算法,i与j一起移动,一般是对二重循环进行优化,从而降低时间复杂度,提高算法效率
模拟过程:
while(loge[i].x-loge[j].x>=d)//超过时间段{cnt[loge[j].y]--;j++;//j指针后移}

知识点:pair<>的用法
(1条消息) C++ pair的基本用法总结(整理)_sevencheng798的博客-CSDN博客
#include
using namespace std;
typedef pairPII;//pair<,>类似与二维数组
#define x first //宏定义,为了代码的简洁
#define y second
const int N=1e5+10;//定义数据
PII loge[N];//储存ts,id
int cnt[N];//用于记录id的点赞个数
bool st[N];//
int main(){int n,d,k;scanf("%d%d%d",&n,&d,&k);for(int i=0;i=d)//超过时间段{cnt[loge[j].y]--;j++;//j指针后移}if(cnt[id]>=k)st[id]=true;}for(int i=0;i<=100000;i++){if(st[i])cout<