-
题目描述
标题:日志统计
小明维护着一个程序员论坛。现在他收集了一份"点赞"日志,日志共有N行。
其中每一行的格式是:
ts id
表示在ts时刻编号id的帖子收到一个"赞"。
现在小明想统计有哪些帖子曾经是"热帖"。如果一个帖子曾在任意一个长度
为D的时间段内收到不少于K个赞,小明就认为这个帖子曾是"热帖"。
具体来说,如果存在某个时刻T满足该帖在[T, T+D)这段时间内(注意是左闭
右开区间)收到不少于K个赞,该帖就曾是"热帖"。
给定日志,请你帮助小明统计出所有曾是"热帖"的帖子编号。
【输入格式】
第一行包含三个整数N、D和K。
以下N行每行一条日志,包含两个整数ts和id。
对于50%的数据, 1 <= K <= N <= 1000
对于100%的数据, 1 <= K <= N <= 100,000
0 <= ts <= 100,000
0 <= id <= 100,000
【输出格式】
按从小到大的顺序输出热帖id。每个id一行。
【输入样例】
7 10 2
0 1
0 10
10 10
10 1
9 1
100 3
100 3
【输出样例】
1
3
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
注意:
main函数需要返回0;
只使用ANSI C/ANSI C++ 标准;
不要调用依赖于编译环境或操作系统的特殊函数。
所有依赖的函数必须明确地在源文件中 #include <xxx>
不能通过工程设置而省略常用头文件。
提交程序时,注意选择所期望的语言类型和编译器类型。
-
解题代码
//日志统计
#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;
vector<int> tiezi[100005];
set<int> id_set;
//行数、时间间隔、点赞阈值
int num, time_Gap, threshold;
bool judge(int id){
//预先筛一波点赞数量少的。
if(tiezi[id].size() < threshold){
return false;
}
//给当前id中的所有时间点进行快速排序。
sort(tiezi[id].begin(), tiezi[id].end());//注意sort函数的用法。
//运用【尺取法】逐段判断是否满足阈值。有点像一个滑动窗口。
int begin = 0;
int end = begin + threshold-1;
while(end < tiezi[id].size()){
if(tiezi[id][end]-tiezi[id][begin] < time_Gap){
//足够点赞数的时间间隔小于设定的时间间隔。满足条件。
return true;
}
end++;
begin++;
}
return false;
}
int main()
{
//输入行数、时间间隔、点赞阈值
scanf("%d%d%d", &num, &time_Gap, &threshold);
for(int i = 0; i < num; i++){
int time, id;
scanf("%d%d", &time, &id);
tiezi[id].push_back(time);
id_set.insert(id);//插入后自动排了序。
}
//迭代每一个id。判断该id在限定时间间隔内对应的时刻数量是否满足阈值。
set<int>::iterator it;//定义用来遍历set的迭代器。
for(it = id_set.begin(); it != id_set.end(); it++){
int id = *it;//获取id。
if(judge(id)){//调用judge函数判断该id是否满足条件 。
cout<<id<<endl;
}
}
return 0;
}
-
思路总结
使用vector<int>类型的数组存放帖子的发布时间,数组的下标代表了帖子的id。这样一个帖子对应一个vector向量。可以通过vector.push_back()函数把当前id对应的发布时刻追加进这个vector向量。必要时刻对vector向量进行快速排序。sort(vector.begin(), vector.end())。
使用set<int>集合来存放帖子的id。好处是,set是一个有序集合,使用insert()函数把id追加进set后,set会自动排序,且保证集合元素的唯一性。
最后通过滑动窗口的方法来判断是否符合条件。这一条件是【在限定时间段内是否有足够多的点赞数】。在本解题思路中,博主使用的方法是:做一个判断---判断足够点赞数的时间间隔是否小于规定的时间间隔。使用这个判断有个好处,那就是我们可以直接确定【足够点赞数的时间间隔】。因为vector中元素的数量就是点赞数量,使用begin--end构成的滑动窗口扫描vector中的元素序列,便可解决我们的问题。
-
经验总结
1. set可以自动排序。 可以使用set集合来存放id。
2. sort(),快速排序函数。
头文件:#include<algorithm>
对于数组a[n], sort的使用方法为:sort(a, a+n);
对于vector<int> a, sort的使用方法为:sort(a.begin(), a.end());
3.使用迭代器遍历set。
set<int>::iterator it;//定义用来遍历set的迭代器。
for(it = id_set.begin(); it != id_set.end(); it++){
int id = *it;//获取id。
//id就是从set中拿到的元素了。
}
//在python中迭代尤为简单┏ (゜ω゜)=☞
for item in list:
//item就是从list中拿到的元素了。