B:Biking Duck

题意:现在有一个人要从(x1,y1)点走到(x2,y2)点, 现在走路的速度为v。 还有骑自行车的速度v2,自行车要从某个自行车站到另一个自行车站,现在我们可以视地图的边界都为自行车站,求最小时间是多少。

题解:对于忽视边界的问题,那就是暴力枚举。现在有了边界, 我们假设一个点在边界,那么我们可以枚举另一个自行车点之后,在某个边界上三分另一个点。 下一个情况就是2个自行车站都在边界上,我们三分套三分去维护找到最小值。

思维不怎么麻烦,就是写的有点麻烦。

代码:

#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<double,double> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod =  (int)1e9+7;
const int N = 1e5 + 100;
pll p[N], x, y, ld, ru;
double v1, v2;
int n;
double dis(pll p1, pll p2){
    return sqrt(pow(p1.fi-p2.fi,2)+pow(p1.se-p2.se,2));
}
double cal(pll p1, pll p2, int fx){
    if(fx == 1 || fx == 3){
        double posy;
        if(fx == 1) posy = ld.se;
        else posy = ru.se;
        double lx = ld.fi, rx = ru.fi;
        for(int i = 0; i < 60; ++i){
            double m = (lx+rx)/2.0;
            double mm = (m+rx)/2.0;
            if((dis(p1,{m,posy})/v2+dis(p2,{m,posy})/v1) > (dis(p1,{mm,posy})/v2+dis(p2,{mm,posy})/v1)) lx = m;
            else rx = mm;
        }
        return dis(p1,{lx,posy})/v2 + dis(p2,{lx,posy})/v1;
    }
    else {
        double posx;
        if(fx == 2) posx = ld.fi;
        else posx = ru.fi;
        double ly = ld.se, ry = ru.se;
        for(int i = 0; i < 60; ++i){
            double m = (ly+ry)/2.0;
            double mm = (m+ry)/2.0;
            if(dis(p1,{posx,m})/v2 + dis(p2,{posx,m})/v1 > dis(p1,{posx,mm})/v2 + dis(p2,{posx,mm})/v1) ly = m;
            else ry = mm;
        }
        return dis(p1,{posx,ly})/v2 + dis(p2,{posx,ly})/v1;
    }
}
double solve(int fx, int ffx){
    if(fx == 1 || fx == 3){
        double posy;
        if(fx == 1) posy = ld.se;
        else posy = ru.se;
        double lx = ld.fi, rx = ru.fi;
        for(int i = 0; i < 60; ++i){
            double m = (lx+rx)/2.0;
            double mm = (m+rx)/2.0;
            if(dis(x,{m,posy})/v1+cal({m,posy},y,ffx) > dis(x,{mm,posy})/v1+cal({mm,posy},y,ffx)) lx = m;
            else rx = mm;
        }

        return dis(x,{lx,posy})/v1+cal({lx,posy},y,ffx);
    }
    else {
        double posx;
        if(fx == 2) posx = ld.fi;
        else posx = ru.fi;
        double ly = ld.se, ry = ru.se;
        for(int i = 0; i < 60; ++i){
            double m = (ly+ry)/2.0;
            double mm = (m+ry)/2.0;
            if(dis(x,{posx,m})/v1+cal({posx,m},y,ffx) > dis(x,{posx,mm})/v1+cal({posx,mm},y,ffx)) ly = m;
            else ry = mm;
        }
        return dis(x,{posx,ly})/v1+cal({posx,ly},y,ffx);
    }
}
int main(){
    scanf("%lf%lf", &v1, &v2);
    scanf("%lf%lf", &ld.fi, &ld.se);
    scanf("%lf%lf", &ru.fi, &ru.se);
    scanf("%lf%lf", &x.fi, &x.se);
    scanf("%lf%lf", &y.fi, &y.se);
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i)
        scanf("%lf%lf", &p[i].fi, &p[i].se);
    double ans = dis(x,y)/v1;
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= n; ++j){
            double tmp = dis(p[i],p[j])/v2+(dis(p[i],x)+dis(p[j],y))/v1;
            ans = min(ans, tmp);
        }
    for(int i = 1; i <= n; ++i){
        ans = min(ans, dis(x,p[i])/v1+cal(p[i],y,1));
        ans = min(ans, dis(x,p[i])/v1+cal(p[i],y,2));
        ans = min(ans, dis(x,p[i])/v1+cal(p[i],y,3));
        ans = min(ans, dis(x,p[i])/v1+cal(p[i],y,4));

        ans = min(ans, dis(y,p[i])/v1+cal(p[i],x,1));
        ans = min(ans, dis(y,p[i])/v1+cal(p[i],x,2));
        ans = min(ans, dis(y,p[i])/v1+cal(p[i],x,3));
        ans = min(ans, dis(y,p[i])/v1+cal(p[i],x,4));
    }
    for(int i = 1; i <= 4; ++i){
        for(int j = 1; j <= 4; ++j){
            ans = min(ans, solve(i,j));
        }
    }
    printf("%.10f\n", ans);
    return 0;
}
View Code

相关文章:

  • 2021-05-24
  • 2022-01-17
  • 2021-11-04
  • 2022-01-22
  • 2022-12-23
  • 2021-06-16
  • 2021-08-06
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-01-15
  • 2022-12-23
  • 2022-01-01
  • 2021-09-15
  • 2021-10-10
相关资源
相似解决方案