poj之旅——3579,3685

本文介绍了一种用于查找数组中第k小数值的有效算法。通过使用二分查找技术和下界搜索,该算法能够在较短时间内找到指定位置的数值。文中提供了两个具体的C++程序实例,分别针对不同类型的输入数据进行演示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接着上次的旅行微笑

此为查找第k小的数的一类题型,基本模式可同最小值最大化。

参考程序:

3579:

#include<cstdio>
#include<algorithm>
#define maxn 110000
using namespace std;
long long half;
int n;
int a[maxn];
bool Check(int mid){
	long long sum=0;
	for (int i=0;i<n;i++)
		sum+=a+n-lower_bound(a+i+1,a+n,a[i]+mid);
	return sum>half;
}
int main(){
	while (scanf("%d",&n)==1){
		for (int i=0;i<n;i++)
			scanf("%d",&a[i]);
		long long m=n*(n-1)/2;
		half=m/2;
		sort(a,a+n);
		int l=0,r=a[n-1]-a[0]+1;
		while (l+1<r){
			int mid=(l+r)>>1;
			if (Check(mid))l=mid;
				else r=mid;
		}
		printf("%d\n",l);
	}
	return 0;
}


3685:

#include<cstdio>
#include<algorithm>
#define oo 100000
#define maxn 51000
using namespace std;
typedef long long LL;
LL n;
LL m;
LL num(LL i,LL j){
	return i*i+oo*i+j*j-oo*j+i*j;
}
bool Check(LL k){
	LL cnt=0;
	for (int j=1;j<=n;j++){
		int l=0,r=n+1;
		while (l+1<r){
			int i=(l+r)>>1;
			if (num(i,j)<k)l=i;
				else r=i;
		}
		cnt+=l;
	}
	return cnt<m;
}
int main(){
	int T;
	scanf("%d",&T);
	while (T--){
		scanf("%lld%lld",&n,&m);
		LL l=-oo*n,r=3*n*n+oo*n;
		while (l+1<r){
			LL mid=(l+r)>>1;
			if (Check(mid))l=mid;
				else r=mid;
		}
		printf("%lld\n",l);
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值