小明维护着一个程序员论坛。现在他收集了一份"点赞"日志,日志共有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 <= 100000 0 <= ts <= 100000 0 <= id <= 100000
【输出格式】
按从小到大的顺序输出热帖id。每个id一行。
【输入样例】
7 10 2
0 1
0 10
10 10
10 1
9 1
100 3
100 3
【输出样例】
1
3
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
解 析:这个题总体来说难度不算太大,我的思路就是记录下每一个帖子id第一次出现的时间,如果这个id又出现了(也就是出现次数>1),先获取该id第一次出现的时间t,然后判断该id现在出现的时间是否在[t,t+d)范围内,如果有效的范围内就让该id的点赞数+1,如果该id的点赞个数>=k(也就是热帖),则用一个Map集合来记录热帖id和该id的点赞数,用Map来存储是因为Map存储的都是键值对类型的数据,可以对热帖id更新其对应的点赞数。最后创建一个可以用来比较的类,把Map中的数据存入一个一个对象中,然后都存入到ArrayList集合中,然后再排一下序,最后输出id即可。
代码如下:
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Scanner;
class STU1 implements Comparable<STU1> //类似于C语言中的结构体
{
private int id; // 热帖id
private int n; // 热帖点赞个数
public STU1(int id,int n)
{
this.id = id;
this.n = n;
}
public int getId()
{
return id;
}
@Override
public int compareTo(STU1 o)
{
if(this.id!=o.id) //按从小到大的顺序输出热帖id
{
return this.id - o.id;
}
return 0;
}
}
public class 日志统计
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
HashMap<Integer,Integer> map = new HashMap<Integer,Integer>(); //记录每一个帖子第一次点赞的时间
HashMap<Integer,Integer> mt = new HashMap<Integer,Integer>(); //记录热帖和其点赞个数
int n = in.nextInt();
int d = in.nextInt();
int k = in.nextInt();
int[] a = new int[100010]; //记录帖子id对应的点赞个数
for(int i=0;i<n;++i)
{
int x = in.nextInt(); //点赞时间
int y = in.nextInt(); //帖子id
if(a[y]==0) //说明第一次出现该帖子id
{
a[y]++; //该帖子点赞数+1
map.put(y,x); //记录下帖子id第一次点赞的时间
}
else //该帖子id不是第一次出现
{
int t = map.get(y); //获取该帖子id第一次出现的时间
if(x>=t&&x<t+d) //题目中的时间限制:[T, T+D)
{
a[y]++; //id对应的点赞数+1
if(a[y]>=k) //超过规定的点赞数,说明是一个热帖
{
mt.put(y,a[y]); //记录下热帖id和其点赞数
}
}
}
}
ArrayList<STU1> stu = new ArrayList<STU1>(); //存放帖子id和点赞个数的集合
for(Integer str : mt.keySet())
{
STU1 stu1 = new STU1(str,mt.get(str)); //先放入一个对象中
stu.add(stu1); //再放入集合
}
Collections.sort(stu); //根据点赞数降序排序
for(int i=0,t=stu.size();i<t;++i)
{
System.out.println(stu.get(i).getId());
}
}
}
运行结果:
输入:
7 10 2
0 1
0 10
10 10
10 1
9 1
100 3
100 3
输出:
1
3