BZOJ 1857: [Scoi2010]传送带【三分】

膜一波 P h D PhD PhD大佬啊~~


三分两个传送带的距离,然后相似算一下坐标:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define db double
#define sg string
#define ll long long
#define rel(i,x,y) for(ll i=(x);i<(y);i++)
#define rep(i,x,y) for(ll i=(x);i<=(y);i++)
#define red(i,x,y) for(ll i=(x);i>=(y);i--)
#define res(i,x) for(ll i=head[x];i;i=nxt[i])
using namespace std;

const ll N=1e5+5;
const ll Inf=1e18;
const db Eps=1e-10;

struct node {
	db x,y;
}pt[5];

db p,q,r;

db getdis(node p,node q) {
	return sqrt((p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y));
}

node getpos(ll x,ll y,db len) {
	db tlen=getdis(pt[x],pt[y]),quo=tlen==0?0:len/tlen;
	return (node){pt[x].x+(pt[y].x-pt[x].x)*quo,pt[x].y+(pt[y].y-pt[x].y)*quo};
}

db f(node x,db len) {
	node tmp=getpos(3,4,len);
	return getdis(x,tmp)/r+(getdis(pt[3],pt[4])-len)/q;
}

db f(db len) {
	node tmp=getpos(1,2,len);
	
	db l=0,r=getdis(pt[3],pt[4]);
	
	while(l+Eps<=r) {
		db lmid=(2*l+r)/3.0,rmid=(l+2*r)/3.0;
		
		if(f(tmp,lmid)>=f(tmp,rmid)) l=lmid;
		else r=rmid;
	}
	
	return len/p+f(tmp,l);
}

int main() {
	rep(i,1,4) scanf("%lf%lf",&pt[i].x,&pt[i].y);
	scanf("%lf%lf%lf",&p,&q,&r);
	
	db l=0.0,r=getdis(pt[1],pt[2]);
	
	while(l+Eps<=r) {
		db lmid=(2*l+r)/3.0,rmid=(l+2*r)/3.0;
		
		if(f(lmid)>=f(rmid)) l=lmid;
		else r=rmid;
	}
	
	printf("%.2lf",f(l));
	
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值