2018 Lanqiao Cup Log Statistics Ruler

How to take Lanqiao Cup log statistics ruler

This is the eighth question of the 2018 Lanqiao Cup C Language Provincial Competition Group B

Title description
Xiao Ming maintains a programmers forum. Now he has collected a "like" log with N lines in total.
The format of each line is: ts id. Indicates that the post numbered id at ts time received a "like".
Now Xiao Ming wants to count which posts were once "hot posts".
If a post has received no less than K likes in any time period of length D, Xiao Ming thinks that the post was once a "hot post".
Specifically, if there is a certain moment T that satisfies that the post receives no less than K likes during the period of [T, T+D) (note that the left is closed and the right is open), the post was once "hot Post".
Given a log, please help Xiao Ming count all the post numbers that were once "hot posts".

Input The
first line contains three integers N, D, and K.
The following N lines have one log per line, containing two integers ts and id.
1 <= K <= N <= 100000 0 <= ts <= 100000 0 <= id <= 100000

Output The
hot post id will be output in ascending order. One line per id.

Sample input
7 10 2
0 1
0 10
10 10
10 1
9 1
100 3
100 3

Sample output
1
3

OJ link

Idea : My idea is to store the like time of each id in a two-dimensional array, that is, maps[id][]=ts. Then use the ruler method to determine the conditions of each id according to the maps array, and if it meets the requirements, it is the answer.
In order to reduce the search for the array, I introduced a set to store the id number that appeared, and then query the array associated with the id number that appeared.

Ruler selection: I think it is to set the first and last positions of a subset in a continuous set, and then continue to advance the first and last positions to find the qualified subset. Because this question needs to calculate the time difference, the data must be in order, so in the code below I use sort to sort the maps array.

AC code :

#include <bits/stdc++.h>
using namespace std;

vector<int>maps[100001]; //二维数组储存每个节点的被点赞的时间 maps[x][0]就是x号帖子第一次被点赞的时间 
set<int>alls; //储存出现的帖子编号  与maps配合 避免不必要的查询 直接maps[alls][]就行 

int main()
{
    
    
	int n,d,k,ts,id;
	scanf("%d %d %d",&n,&d,&k);
	
	while(n--)
	{
    
    
		scanf("%d %d",&ts,&id);
		alls.insert(id); //储存出现的id号 
		maps[id].push_back(ts);	//将点赞时间储存至maps[id][] 
	}
	
	for(set<int>::iterator iter=alls.begin();iter!=alls.end();iter++) //对整个maps[alls][]数组进行排序 方便后面的时间统计 
	{
    
    
		sort(maps[*iter].begin(),maps[*iter].end()); //对有数据的数组进行排序 即 maps[alls][]
	} 
	
	for(set<int>::iterator iter=alls.begin();iter!=alls.end();iter++) //对有数据的maps数组进行查找  
	{
    
    
		int all=0,first=0,end=0; //点赞数量 第一个赞的位置 最后一个赞的位置 
		while(1) //尺取法 
		{
    
    
			while(all<k&&end<maps[*iter].size()) //点赞数小于要求 && 数组里的数据还没有统计完 
			{
    
    
				all++; 
				end++;
			}
			if(all<k) //统计完了 赞也不够 
				break;
			if(maps[*iter][end-1]-maps[*iter][first]<d) //赞够 并且 第一个赞和末尾赞的时间相隔符合要求 
			{
    
    
				printf("%d\n",*iter); //由于set有序 所以直接输出即可 
				break;
			}
			all--;
			first++; 
		}
	} 
	
	return 0;
}

Guess you like

Origin blog.csdn.net/qq_45698148/article/details/108255123