Meeting on the Line(贪心,二分,三分)

Meeting on the Line(贪心算法)(二分,三分)

题目大意:类似(实数版)货仓选址,给你n个位置(不用再这n个位置中选,可以任意选实数),再给你这n个位置出发的准备时间(可以转化成距离来看),求一个位置,到每个位置的最大值最小

AC代码(贪心思想,类似货仓选址)

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=100010;
const int INF=0x3f3f3f3f;
int x[maxn],t[maxn];
int main(void)
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		int N;scanf("%d",&N);
		for(int i=0;i<N;i++)scanf("%d",&x[i]);
		int l=INF,r=-INF;
		for(int j=0;j<N;j++)
		{
			scanf("%d",&t[j]);
			l=min(l,x[j]-t[j]);//把多出来的准备时间看成位置,那么就可以延长他的距离
			r=max(r,x[j]+t[j]);//最后找出来最左边的位置和最右边的位置,取个中间的值,就可以得到到所有位置的最大值满足最小
		}
		printf("%.1lf\n",1.0*(l+r)/2);
	}
	return 0;
}

AC代码(三分)

#include <cstdio>//三分有个特点,就是要把区间除以三,导致很多的实数区间再除以三之后会有很多的小数位
#include <iostream>//所以三分在输出答案的时候要特别注意,输出的小数点的位数一定要比答案给的精度多两三位
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iomanip>
using namespace std;
const double e=1e-8;
const int maxn=200010;
const int INF=0x3f3f3f3f;
double pos[maxn],t[maxn];
int N;
double check(double x)
{
	double Max=0;
	for(int i=0;i<N;i++)
		Max=max(Max,abs(x-pos[i])+t[i]);
	return Max;
}
int main(void)
{
	int T;scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&N);
		long double l=0,r=INF;
		for(int i=0;i<N;i++)
			scanf("%lf",&pos[i]);
		for(int i=0;i<N;i++)
			scanf("%lf",&t[i]);
		while(r-l>e)//经典三分
		{
			double midl=l+(r-l)/3;
			double midr=l+(r-l)/3*2;
			if(check(midr)>check(midl)) r=midr;
			else l=midl;
		}
		cout<<setprecision(7)<<r<<endl;//题目是要误差小于1e-6,所以输出1e-7的话基本就没什么问题了
	}
	return 0;
}

AC代码(二分)

//可以二分时间或者位置,这里二分位置,(时间和位置是可以相互转换的)

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cmath>
using namespace std;
const double e=1e-7;//不太清楚为什么1e-8会超时,明明1e-7的时间很短
const int maxn=100010;
const int INF=0x3f3f3f3f;
int pos[maxn],t[maxn];
int N;
bool check(double x)
{
	double l=0,r=0;
	for(int i=0;i<N;i++)
	{
		if(x>pos[i])l=max(l,x-pos[i]+t[i]);
		else r=max(r,pos[i]+t[i]-x);
	}
	return r>=l;
}
int main(void)
{
	int T;scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&N);
		for(int i=0;i<N;i++)scanf("%d",&pos[i]);
		for(int j=0;j<N;j++)scanf("%d",&t[j]);
		double l=0,r=INF;
		while(r-l>e)
		{
			double mid=(r+l)/2;
			if(check(mid)) l=mid;
			else r=mid;
		}
		printf("%.7lf\n",r);
	}
	return 0;
}
posted @ 2022-09-27 22:34  WUTONGHUA02  阅读(169)  评论(0编辑  收藏  举报