【SCOI2010】【三分法】传送带

本文介绍了一种使用三分法解决特定路径最小值问题的方法。通过递归地将路径分为三段,并根据每段的代价调整搜索范围,最终找到使路径代价最小的分割点。代码实现了完整的算法流程,包括输入输出、点结构定义、距离计算等。

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

很早就知道了这题可以三分,但当时我听到的说法是三分套三分,就退缩了- -。

今天理解了一下某位神牛的代码,写的很巧妙,挺好懂的。要注意需要判断三分出来的两个点是否重合,如果重合的话要选择左边一个点。

代码:

#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
const double eps = 1e-12;
struct Point
{
	double x,y;
	Point(double u = 0,double v = 0){x = u;y = v;}
	Point operator +(const Point &A){return Point(x + A.x,y + A.y);}
	Point operator -(const Point &A){return Point(x - A.x,y - A.y);}
	Point operator /(const double &A){return Point(x / A,y / A);}
};
Point a[2],b[2],P[2];
double p,q,r;
double sqr(double x){return x * x;}
void read(Point &A){scanf("%lf%lf",&A.x,&A.y);}
void init()
{
	freopen("bzoj1857.in","r",stdin);
	freopen("bzoj1857.out","w",stdout);
}

void readdata()
{
	for(int i = 0;i < 2;i++)
	{
		read(a[i]);read(b[i]);
	}
	scanf("%lf%lf%lf",&p,&q,&r);
}

double dist(Point A,Point B)
{
	return sqrt(sqr(B.x - A.x) + sqr(B.y - A.y));
}

double getA()
{
	return dist(a[0],P[0]) / p + dist(P[0],P[1]) / r + dist(P[1],b[1]) / q;
}

double divide3(int k)
{
	Point L = a[k],R = b[k],M1,M2,del;
	double A1,A2;
	while(dist(L,R) > eps)
	{
		del = (R - L) / 3;
		M1 = L + del;M2 = R - del;
		P[k] = M1;
		if(k)A1 = divide3(1 - k); else A1 = getA();
		P[k] = M2;
		if(k)A2 = divide3(1 - k); else A2 = getA();
		if(A1 < A2)R = M2;else L = M1;
	}
	if(dist(a[k],b[k]) <= eps)
	{
		P[k] = a[k];
		if(k)return divide3(1 - k);
		else return getA();
	}
	return A1;
}

void solve()
{
	double ans = divide3(1);
	printf("%.2lf\n",ans);
}

int main()
{
	init();
	readdata();
	solve();
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值