2018Lanqiaoカップログ統計定規

Lanqiaoカップログ統計定規を取る方法

これは、2018 Lanqiao CupC言語地方大会グループBの8番目の質問です。

タイトルの説明
XiaoMingは、プログラマーフォーラムを維持しています。現在、彼は合計N行の「いいね」ログを収集しました。
各行の形式は次のとおりです。tsid。ts時に投稿番号が付けられたIDが「いいね」を受け取ったことを示します。
Xiao Mingは、かつて「ホットな投稿」だった投稿を数えたいと考えています。
投稿が長さDのいずれかの期間にK件以上のいいねを受け取った場合、XiaoMingはその投稿がかつて「ホット投稿」であったと見なします。
具体的には、[T、T + D)の期間中に投稿がK件以上のいいねを受け取ることを満足する特定のモーメントTがある場合(左が閉じ、右が開いていることに注意)、投稿はかつて「ホットポスト」。
ログがあれば、XiaoMingがかつて「ホットな投稿」だったすべての投稿番号を数えるのを手伝ってください。

入力
最初の行には、3つの整数N、D、およびKが含まれています。
次のN行には、1行に1つのログがあり、2つの整数tsとidが含まれています。
1 <= K <= N <= 100000 0 <= ts <= 100000 0 <= id <= 100000

出力
ホットポストIDが昇順で出力されます。IDごとに1行。

サンプル入力710
2
0 1
0 10
10 10
10 1
9
1100
3100 3

サンプル出力
1
3

OJリンク

アイデア:私のアイデアは、各IDの同じ時間を2次元配列に格納することです。つまり、maps [id] [] = tsです。次に、ルーラーメソッドを使用して、maps配列に従って各IDの条件を決定します。要件を満たしている場合は、それが答えです。
配列の検索を減らすために、表示されたID番号を格納するセットを導入し、表示されたID番号に関連付けられた配列を照会しました。

ルーラーの選択:サブセットの最初と最後の位置を連続セットに設定してから、最初と最後の位置を進めて、修飾されたサブセットを見つけることだと思います。この質問では時差を計算する必要があるため、データは順番に並べられている必要があります。以下のコードでは、sortを使用してマップ配列を並べ替えています。

ACコード

#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;
}

おすすめ

転載: blog.csdn.net/qq_45698148/article/details/108255123