题目:
标题:日志统计
小明维护着一个程序员论坛。现在他收集了一份"点赞"日志,日志共有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
思路:
该题的难点在于如何处理一个编号id对应多个时刻ts,可以用数组或者工具类Set存储id。
然后就是如何判断 某个编号对应的时刻ts 是否在[T, T+D)这段时间内,如果收到不少于K个赞,该帖就曾是"热帖"。
求解:
我只测试了部分数据,可能会存在bug,仅供参考。
public class 日志统计 {
static int N = 100005; //最大日志数
static ArrayList[] tsLists = new ArrayList[N]; //存储帖子的点赞时刻
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
Set<Integer> postId = new TreeSet<Integer>(); //存储帖子的id,TreeSet自带自然排序
int n = input.nextInt(); //日志数
int d = input.nextInt(); //时间增长区间
int k = input.nextInt(); //赞数量
//通过id对获赞时间分类
for(int i=0; i<n; i++) {
int ts = input.nextInt(); //ts时刻
int id = input.nextInt(); //编号id的帖子
//记录帖子id
postId.add(id);
//存储帖子点赞时刻
if(tsLists[id] == null)
tsLists[id] = new ArrayList<Integer>();
tsLists[id].add(ts);
}
//对帖子点赞时刻排序
for(int i=0; i<N; i++) {
if(postId.contains(i) == false) //不存在的id跳过
continue;
//按升序排序点赞时刻
Object[] arr = tsLists[i].toArray();
Arrays.sort(arr);
boolean flag = false; //标识是否是“热帖”
for(int j=arr.length-1; j>=0; j--) {//注意题意,如果存在某个时刻T满足该帖在[T, T+D)这段时间内
for(int kk=0; kk<=j; kk++) {// (注意是左闭右开区间)收到不少于K个赞,该帖就曾是"热帖"。
if((int)arr[j]-(int)arr[kk]<d && (j-kk+1)>=k) { //这里:arr[j]-arr[kk]<d 判断是否在时间段内
flag = true; //j-kk+1:计算点赞数,即求kk-j之间的点赞数
break;
}
}
//当前id的帖子为“热帖”,跳出
if(flag) {
System.out.println(i);
break;
}
}
/* for(int j=0; j<arr.length; j++) {
System.out.print(arr[j]+" ");
}
System.out.println();*/
}
}
}