代码:
#include<iostream>
#include<vector>
#include<algorithm>
#include<climits>
using namespace std;
struct post{
int ts;
int id;
}ps[100005];
bool hotTag[100005];
int countNum[100005];
int startID=INT_MAX,endID=0;//为了获取有效区间
bool comparison(post a,post b){
if(a.id<b.id) return true;
else if(a.id==b.id)
{
if(a.ts<b.ts) return true;
else return false;
}
else return false;
}
int main()
{
//k个赞就是热帖
//相差d时间段内
int n,d,k;
cin>>n>>d>>k;
for(int i=0;i<n;i++)
{
cin>>ps[i].ts>>ps[i].id;
if(ps[i].id>endID) endID=ps[i].id;
if(ps[i].id<startID) startID=ps[i].id;
}
sort(ps,ps+n,comparison);
for(int i=0;i<n;i++)
{
int t1=ps[i].ts;
int id1=ps[i].id;
countNum[id1]=1;
if(hotTag[id1]) continue;
for(int j=i+1;j<n;j++)
{
int t2=ps[j].ts;
int id2=ps[j].id;
if(t2-t1>=d) break;
if(id2!=id1) break;
countNum[id1]++;
}
if(countNum[id1]>=k) hotTag[id1]=true;//不能放到循环里面,循环里面是判断除了自己还有多少,而这个判断标准是判断总数。
}
for(int i=startID;i<=endID;i++)
{
if(hotTag[i]) cout<<i<<endl;
}
return 0;
}
初步优化的方式就是减去无效计算,减少无效计算的一种方法就是要重点关注题目的问题域,尽量不要计算问题域之外的数据。
我们以id作为第一关键字进行从小到大排序,同时以时间作为第二关键字,从小到大进行排序。最终我们得到了一个相同id的数据聚集在一起,而且这些id还以时间从小到大进行排序。这样我们在遍历id计算点赞数的时候就不需要重复遍历那些与本次计算的id不同的id了,这些遍历都是无效遍历。同时遍历时超过t+d这个时间段之外的点赞不在遍历,这样就是省下来重复遍历那些根本不在合理时间段要求内的点赞的算力。这两种优化就能保证题目通过。
b站讲解地址:蓝桥杯·寒假百校真题大联赛(大学B组)(第5期)题目讲解:日志统计_哔哩哔哩_bilibili