刷题总结——传送带(四川省选)
题目:
题目背景
SCOI2010 DAY2 T2
题目描述
在一个 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 位。
样例数据 1
备注
【数据范围】
对于 100% 的数据,1≤Ax,Ay,Bx,By,Cx,Cy,Dx,Dy≤1000 ;1≤P,Q,R≤10 。
题解:
三分套三分,第一个三分枚举AB上的点,第二个三分枚举CD上的点;
代码:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<ctime> #include<cctype> #include<string> #include<algorithm> #include<cstring> using namespace std; struct point { double x; double y; }a,b,c,d; double Fabs(double a) { if(a<0) return -a; else return a; } double dis(point a,point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } double Vab,Vcd,V; double calc(point e) { double ans; point left=c,right=d; for(int t=1;t<=1000;t++) { point temp1,temp2; temp1.x=left.x+(right.x-left.x)/3; temp1.y=left.y+(right.y-left.y)/3; temp2.x=right.x-(right.x-left.x)/3; temp2.y=right.y-(right.y-left.y)/3; double ans1=dis(a,e)/Vab+dis(e,temp1)/V+dis(temp1,d)/Vcd,ans2=dis(a,e)/Vab+dis(e,temp2)/V+dis(temp2,d)/Vcd; if(ans1>ans2) ans=ans2,left=temp1; else ans=ans1,right=temp2; } return ans; } int main() { //freopen("a.in","r",stdin); scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y); scanf("%lf%lf%lf%lf",&c.x,&c.y,&d.x,&d.y); scanf("%lf%lf%lf",&Vab,&Vcd,&V); double ans; point left=a,right=b; for(int t=1;t<=1000;t++) { point temp1,temp2; temp1.x=left.x+(right.x-left.x)/3; temp1.y=left.y+(right.y-left.y)/3; temp2.x=right.x-(right.x-left.x)/3; temp2.y=right.y-(right.y-left.y)/3; double ans1=calc(temp1),ans2=calc(temp2); if(ans1>ans2) ans=ans2,left=temp1; else ans=ans1,right=temp2; } printf("%0.2lf",ans); return 0; }