【每日蓝桥】59、一八年省赛Java组真题“日志统计”

175 阅读4分钟

这是我参与更文挑战的第6天,活动详情查看: [更文挑战]

你好呀,我是灰小猿,一个超会写bug的程序猿!

欢迎大家关注我的专栏“每日蓝桥”,该专栏的主要作用是和大家分享近几年蓝桥杯省赛及决赛等真题,解析其中存在的算法思想、数据结构等内容,帮助大家学习到更多的知识和技术!

标题:日志统计

小明维护着一个程序员论坛。现在他收集了一份”点赞”日志,日志共有 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

资源约定: .

峰值内存消耗(含虚拟机) < 256M

CPU消耗< 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“ 请您输...”的多余内容.

所有代码放在同-一个源文件中,调试通过后,拷贝提交该源码.

不要使用package语句。不要使用jdk1.7及以上版本的特性。

主类的名字必须是: Main, 否则按无效代码处理.

解题思路

本题在求解的时候,我们可以考虑先将用户输入的每个帖子的点赞时间记录下来,然后对该点赞时间进行排序,找出在区间D内点赞数量最多的那个区间,只要在D区间内的点赞数量大于K,则将其存储到SortedSet中,SortedSet是一个可以对元素进行自动排序,且输入数据不重复的数据类型,对每一个帖子及其点赞时间的存储可以使用map,key为整型数据,表示帖子的编号,后面的value为list列表,其中存储该编号帖子的点赞时间,最后按照上述方法进行判断即可。

答案源码:

package 一八年省赛真题;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

public class Year2018_Bt8 {

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int N = scanner.nextInt();	//帖子数量
		int D = scanner.nextInt();	//时间
		int K = scanner.nextInt();	//热帖指标
		Map<Integer, List<Integer>> tiezhi = new HashMap<Integer, List<Integer>>();
		HashSet<Integer> idSet = new HashSet<Integer>();
//		int [][] dataArr = new int[N][2];
		SortedSet<Integer> ansSet = new TreeSet<Integer>();
		for (int i = 0; i < N; i++) {
			int ts = scanner.nextInt();	//点赞时间
			int id = scanner.nextInt();	//点赞的帖子号
			
			idSet.add(id);
			//如果数据是第一次记录
			if (tiezhi.get(id)==null) {
				List<Integer> list = new ArrayList<Integer>();
//				System.out.println(id + " " + ts);
				list.add(ts);
				tiezhi.put(id, list);
			} else {
				List<Integer> list = new ArrayList<Integer>();
				list = tiezhi.get(id);
//				System.out.println(id + " " + ts);
				list.add(ts);
				tiezhi.put(id, list);
			}											
		}
		//遍历每一个存储的帖子的id
		for (Integer ids : idSet) {
			//将每一个帖子对应的点赞时间放置到数组中,并对该数组排序
			List<Integer> list = tiezhi.get(ids);
			int [] tsArr = new int[list.size()];
			for (int i = 0; i < list.size(); i++) {
//				System.out.print(ids + ": " + list.get(i) + " ");
				tsArr[i] = list.get(i);
			}
			Arrays.sort(tsArr);
			
			//遍历存放时间的数组,看其中在D时间区间内有没有点赞数大于K的情况
			for (int i = 0; i < tsArr.length; i++) {
				int j = i;
				int count = 0;
				while(j<tsArr.length && (tsArr[j]-tsArr[i])<D) {
//					System.out.println(ids + " " + tsArr[j] + "-" + tsArr[i]);
					count++;
					j++;
				}
				//如果存在点赞数大于K的帖子,则记录id
				if (count>=K) {
					ansSet.add(ids);
				}
			}
		}
		
		for (Integer integer : ansSet) {
			System.out.println(integer);
		}		
					
	}

}

输出样例:

其中有不足或者改进的地方,还希望小伙伴留言提出,一起学习!

感兴趣的小伙伴可以关注专栏!

灰小猿陪你一起进步!