省流:将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:要是有不对的地方,或者更好的地方欢迎指正!