【蓝桥杯】1238. 日志统计*(双指针)

穿越隧道

更简洁版

因对pair排序,就是先按照第一个关键字从小到达排序,然后按照第二个从小到大排序。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>
#include <cmath>
#define x first
#define y second
using namespace std;
typedef pair<int,int> pii;
const int N = 1e6 + 10;
int n,d,k;
int kk;
pii a[N]; 
int path[N];
int mp[N];
bool st[N];
int main(){
	scanf("%d%d%d",&n,&d,&k);
	for(int i = 0; i < n; i++){
		scanf("%d%d",&a[i].x,&a[i].y);
	}
	sort(a,a + n);
	for(int i = 0,j = 0; i < n; i++){
		mp[a[i].y]++;
		while(a[i].x - a[j].x >= d){
			mp[a[j].y]--;
			j++;
		}
		if(mp[a[i].y] >= k){
			st[a[i].y] = true;
		}
	}
	for(int i = 0; i < N; i++){
		if(st[i])
			cout << i << endl;
	}
	return 0;
}

简洁版

#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>
#include <cmath>
#define x first
#define y second
using namespace std;
typedef pair<int,int> pii;
const int N = 1e6 + 10;
int n,d,k;
int kk;
pii a[N]; 
int path[N];
int mp[N];
bool st[N];
bool cmp(pii a, pii b){
	if(a.x == b.x){
		return a.y < b.y;
	}
	return a.x < b.x;
}
int main(){
	scanf("%d%d%d",&n,&d,&k);
	for(int i = 0; i < n; i++){
		scanf("%d%d",&a[i].x,&a[i].y);
	}
	sort(a,a + n,cmp);
	for(int i = 0,j = 0; i < n; i++){
		mp[a[i].y]++;
		while(a[i].x - a[j].x >= d){
			mp[a[j].y]--;
			j++;
		}
		if(mp[a[i].y] >= k){
			st[a[i].y] = true;
		}
	}
	for(int i = 0; i < N; i++){
		if(st[i])
			cout << i << endl;
	}
	return 0;
}

复杂冗余版

错误在于:判断日志的赞的答案的代码的顺序应该放在for循环的下面,否则会遗漏答案

#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>
#include <cmath>
#define x first
#define y second
using namespace std;
typedef pair<int,int> pii;
const int N = 1e6 + 10;
int n,d,k;
int kk;
pii a[N]; 
int path[N];
int mp[N];
bool st[N];
bool cmp(pii a, pii b){
	if(a.x == b.x){
		return a.y < b.y;
	}
	return a.x < b.x;
}
int main(){
	scanf("%d%d%d",&n,&d,&k);
	for(int i = 0; i < n; i++){
		scanf("%d%d",&a[i].x,&a[i].y);
	}
	sort(a,a + n,cmp);
	for(int i = 0,j = 0; i < n; i++){
		mp[a[i].y]++;
		while(a[i].x - a[j].x >= d){
			mp[a[j].y]--;
			j++;
		}
		//顺序问题很重要,if代码段要放在下面,因当时间段大于等于d时,其中可能存在符合的答案
		if(a[i].x - a[j].x < d){
			if(mp[a[i].y] >= k && !st[a[i].y]){
				path[kk++] = a[i].y;
				st[a[i].y] = true;
			}
		}
	}
	sort(path,path+kk);
	for(int i = 0; i < kk; i++){
		cout << path[i] << endl;
	}
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值