日志统计(双指针,滑动窗口找合格的子区间)

日志统计(双指针,滑动窗口找合格的子区间)

日志统计(双指针,滑动窗口找合格的子区间)_第1张图片

细节错误

1、对数组排序的规则,其实只要对于同一id的帖子按照点赞时间非降序排序就ok,对于帖子的id没必要(不影响)升序排序(下面那种错误的办法,边判断边输出,碍于需要按id升序输出结果,才需要对id升序)
2、时间段相差最大值是 d-1
日志统计(双指针,滑动窗口找合格的子区间)_第2张图片
相差为d也是不可以的,所以要取等号

while(a[r].ts>=a[l].ts+d){//区间右移,
//			  主要是为了满足ts的要求而不得不舍弃前面的点赞
//而且要清楚这里同一个id的帖子,可能不止一个子区间满足条件,
//也就是不同的r对应的是同一个a[r].id,不能直接输出否则会重复,只能通过st数组记录
	  			cnt[a[l].id]--;
	  			l++;
			}

2、n 是点赞数量,而不是帖子数量,帖子的编号同0开始,最大范围是 100000
3、最后的输出, 关于超时,用cout输出即使加上

  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);

照样超时,用printf最好!
日志统计(双指针,滑动窗口找合格的子区间)_第3张图片
第一个评测,bitch!
试试这个网站!
日志统计(双指针,滑动窗口找合格的子区间)_第4张图片

#include 
#include 
using namespace std;
#define int long long int
int n,d,k;
const int N=1e5+5;

struct node{
    int ts,id;
    bool operator<(const node & b)const{
        if(id==b.id)return ts<b.ts;
        else return id<b.id;
    }
}a[N];
int cnt[N];//
bool st[N];
signed main(){
      cin>>n>>d>>k;
      for(int i=1;i<=n;i++){
          cin>>a[i].ts>>a[i].id;
      }
      sort(a+1,a+n+1);
      
      int l=1;//指向当前帖子的下标
      for(int r=1;r<=n;r++){
              cnt[a[r].id]++;//该id的帖子多一个赞
              while(a[r].ts>=a[l].ts+d){//区间右移,
//              主要是为了满足ts的要求而不得不舍弃前面的点赞
//而且要清楚这里同一个id的帖子,可能不止一个子区间满足条件,
//也就是不同的r对应的是同一个a[r].id,不能直接输出否则会重复,只能通过st数组记录
                  cnt[a[l].id]--;
                  l++;
            }
            if(cnt[a[r].id]>=k)st[a[r].id]=true;
      }
    
    for(int i=0;i<=100000;i++)if(st[i])printf("%d\n",i);
   // cout<
  return 0;
}

思路错误纠正

日志统计(双指针,滑动窗口找合格的子区间)_第5张图片

  • 首先,思路错误,用l左指针固定地指向 同一id中最早获赞的那个帖子,只判断 区间【l,i】这段区间(最先获赞的一些帖子)是否满足,实际上对于同一个id的帖子,【L,R】任意子区间都可能满足
if(a[i].id==a[l].id){
	 if(a[i].ts-a[l].ts<d)tmp++;
}
  • 其次,n 是点赞数量,而不是帖子数量,帖子的编号同0开始,最大范围是 100000

以下代码错的!

#include 
#include 
using namespace std;
#define int long long int
int n,d,k;
const int N=1e5+5;

struct node{
	int ts,id;
	bool operator<(const node & b)const{
		if(id==b.id)return ts<b.ts;
		else return id<b.id;
	}
}a[N];
bool st[N];
signed main(){
	  cin>>n>>d>>k;
	  for(int i=1;i<=n;i++){
	  	cin>>a[i].ts>>a[i].id;
	  }
	  sort(a+1,a+n+1);
	  int tmp=1;//当前帖子得到的赞
	  int l=1;//指向当前帖子的下标
	  for(int i=2;i<=n;i++){
	  	if(a[i].id==a[l].id){
	  		if(a[i].ts-a[l].ts<d)tmp++;
		}
		else {
			if(tmp>=k)st[l]=true;//cout<
			tmp=1;//注意了,这是第一个编号为i的帖子的获赞,tmp为1不为0
			l=i;
		}
	  }
	  if(tmp>=k)st[l]=true;//cout<
	for(int i=0;i<=100000;i++)if(st[i])cout<<a[i].id<<endl;
  return 0;
}

你可能感兴趣的:(贪心,思维,构造,c++,算法,开发语言)