时间限制: 1Sec 内存限制: 128MB 提交: 873 解决: 213
题目描述
小明维护着一个程序员论坛。现在他收集了一份"点赞"日志,日志共有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
AC
#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
#include<set>
using namespace std;
const int inf=0x3fffffff;
const int maxn=10010;
map< int, vector<int> > mp;
map< int, vector<int> >::iterator it;
set<int> ans;
set<int>::iterator it3;
int main(){
int n,d,k;
scanf("%d%d%d",&n,&d,&k);
int ts,td;
for(int i=0;i<n;i++){
scanf("%d%d",&ts,&td);
mp[td].push_back(ts);
}
for(it=mp.begin();it!=mp.end();it++){
int id = it->first ;
vector<int> tss=it->second;
sort(tss.begin(),tss.end());
// id ts1 ts2 ts3 ...... tsn
// 1 0 9 10
// 3 100 100
// 10 0 10
for(int i=0;i<tss.size();i++){
int time = tss[i];
int len = time + d;
int cnt = 0;
for(int j=i;j<tss.size() && tss[j] < len ;j++)
cnt++;
if(cnt>=k){
ans.insert(id);
break;
}
}
}
for(it3=ans.begin();it3!=ans.end();it3++){
printf("%d\n",(*it3));
}
return 0;
}
89% 时间超限 (和AC代码思路一样 只不过换了下映射方法)
#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
#include<set>
using namespace std;
map<int, vector<int> > mp;
map<int, vector<int> >::iterator it,it1;
int main(){
int n,d,k;
scanf("%d%d%d",&n,&d,&k);
int ts,td;
for(int i=0;i<n;i++){
scanf("%d%d",&ts,&td);
mp[ts].push_back(td);
}
int len;
set<int> ans;
set<int>::iterator it3;
map<int,int> cnt;
vector<int> records;
// 0 1 10
// 9 1
// 10 1 10
// 100 3 3
it1=mp.begin();
for(it=mp.begin();it!=mp.end();it++){
while(it1!=mp.end() && it1->first < it->first + d){
records = it1->second;
len = records.size();
for(int i=0;i<len;i++){
cnt[ records[i] ]++;
if( cnt[ records[i] ] >= k)
ans.insert( records[i] );
}
it1++;
}
records = it->second;
len = records.size();
for(int i=0;i<len;i++)
cnt[ records[i] ]--;
}
for(it3=ans.begin();it3!=ans.end();it3++)
cout<<(*it3)<<endl;
return 0;
}
89% 时间超限
#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
#include<set>
using namespace std;
const int inf=0x3fffffff;
const int maxn=10010;
struct node{
int ts,td;
};
bool cmp(node a,node b){
return a.ts<b.ts;
}
int main(){
int n,d,k;
scanf("%d%d%d",&n,&d,&k);
vector<node> records(n);
for(int i=0;i<n;i++)
scanf("%d%d",&records[i].ts,&records[i].td);
sort(records.begin(),records.end(),cmp);
set<int> ans;
set<int>::iterator it;
map<int,int> cnt;
int j=0;
for(int i=0;i<n;i++){
while(j<n && records[j].ts < records[i].ts + d){
cnt[ records[j].td ]++;
if(cnt[ records[j].td ] >= k)
ans.insert(records[j].td);
j++;
}
cnt[ records[i].td ]--;
}
for(it=ans.begin();it!=ans.end();it++)
cout<<(*it)<<endl;
return 0;
}
11% 二维数组简单模拟