牛客[SCOI2010]传送带

省流:将AB,CD平分成1000份,然后两两配对,算出时间,枚举出最小值。

题目:传送门

在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段。两条传送带分别为线段AB和线段CD。lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R。现在lxhgww想从A点走到D点,他想知道最少需要走多长时间。

输入描述:

输入数据第一行是4个整数,表示A和B的坐标,分别为Ax,Ay,Bx,By 

第二行是4个整数,表示C和D的坐标,分别为Cx,Cy,Dx,Dy 

第三行是3个整数,分别是P,Q,R

输出描述:

输出数据为一行,表示lxhgww从A点走到D点的最短时间,保留到小数点后2位

这题正解应该是三分,在牛客写的题,但是我在洛谷看dalao题解的时候发现这题竟然还能暴力(暴力万岁),所以就看着大佬'minamoto'的写法仿写了一个。

思路就是将AB,CD平分成1000份(1000怎么来的?头铁 铁出来的吧,后面我发现其实100也就能ac了哈哈哈),然后点点连接,一一算出时间,枚举出最小值。细节在代码里(也没什么细节),感觉暴力的代码还是很好看懂的,不过我也加了批注。

 上ac代码:

#include<bits/stdc++.h>
using namespace std;
typedef double de;
const int N = 1000;//分量,这题数据不大,100也行
de abx[N+10],cdx[N+10],aby[N+10],cdy[N+10];
de t1[N+10],de t2[N+10];
de ans = 1e18;

inline de dis(int i, int j){//算距离
	return sqrt((pow((abx[i] - cdx[j]),2) + pow((aby[i] - cdy[j]),2)));
}

de ax,ay,bx,by,cx,cy,dx,dy,p,q,r;

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	
	cin >> ax >> ay >> bx >> by >> cx >> cy >> dx >> dy >> p >> q >> r;
	
	de x = (bx - ax)/N, y = (by - ay)/N;//偏移量,将线段平分成1000个点
	for(int i = 0; i <= N; i ++){
		//在ab上枚举点e,并且将偏移后的值重新存储
		abx[i] = ax + x*i;
		aby[i] = ay + y*i;
		
		t1[i] = sqrt(pow(x*i,2) + pow(y*i,2)) / p;//算a到该点e的时间
	}
	
	x = (dx - cx)/N, y = (dy - cy)/N;
	for(int i = 0; i <= N; i ++){
		//在cd上枚举点f
		cdx[i] = dx - x*i;
		cdy[i] = dy - y*i;
		
		t2[i] = sqrt(pow(x*i,2) + pow(y*i,2)) / q;//算该点f到d的时间
	}
	
	for(int i = 0; i <= N; ++i){
		for(int j = 0; j <= N; ++j){
			ans = min(ans,(t1[i] + t2[j] + dis(i,j)/r));//枚举最小的时间
		}
	}
	printf("%.2lf\n",ans);
}

Ps:要是有不对的地方,或者更好的地方欢迎指正!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值