Car的旅行路線(Floyd+模擬)

題目地址

賊雞兒猥瑣的一道題ios

好在數據不毒瘤,並且Floyd就OK了。spa

這道題的難點在於 建圖,也很考驗模擬能力,須要十分的有耐心。code

建圖

題目中告訴了咱們一個矩形的三個點get

咱們在平面直角座標系中隨便畫出一個直角三角形,假設(x1,y1)是直角的這個點,(x4,y4)是咱們要求的第四個點,那麼:string

\[x_4=x_2+x_3-x_1,y_4=y_2+y_3-y_1\]it

(由於我畫圖太渣只好文字解說)io

咱們嘗試在原直角三角形的基礎上把整個矩形畫出來,矩形的四個頂點分別平行於座標軸作平行線,獲得了一個平行於座標軸的大矩形EFGH,發現這裏面有一些全等三角形,你就能證實出上面的結論了。class

Q: 咱們怎麼知道哪一個點是直角點呢?stream

A: 利用勾股定理逆定理。基礎

建圖部分就這樣解決了。

求解

暴力雙精度小數Floyd。

Code

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define N 507
using namespace std;
inline int read() {
    int x=0,f=1; char ch=getchar();
    while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); }
    return x * f;
}
int n,s,t,A,B,cnt;
int T[N];
double g[N][N];
struct Point {
    int x,y,c;  //c就是哪一個城市 
}P[N];
inline int Dis(Point p1,Point p2) {
    return (p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y);   //爲了方便計算,這個是距離的平方 
}
void work() {
    cnt = 0;    //初始化
    s = read(), t = read(), A = read(), B = read();
    for(int i=1;i<=s;++i) {
        for(int j=1;j<=3;++j) {
            P[++cnt].x = read(), P[cnt].y = read(), P[cnt].c = i;
        }
        T[i] = read();
        int a = Dis(P[cnt-2],P[cnt-1]), b = Dis(P[cnt-2],P[cnt]), c = Dis(P[cnt-1],P[cnt]), x4, y4;
        int x1=P[cnt-2].x, x2=P[cnt-1].x, x3=P[cnt].x, y1=P[cnt-2].y, y2=P[cnt-1].y, y3=P[cnt].y;
        if(a+b == c) x4 = x2+x3-x1, y4 = y2+y3-y1;
        if(a+c == b) x4 = x1+x3-x2, y4 = y1+y3-y2;
        if(b+c == a) x4 = x1+x2-x3, y4 = y1+y2-y3;
        P[++cnt].x = x4, P[cnt].y = y4, P[cnt].c = i;
    }
    memset(g,0x3f,sizeof(g));
    for(int i=1;i<=4*s;++i) {
        for(int j=1;j<=4*s;++j) {
            if(i == j) continue;
            double dis = sqrt(Dis(P[i],P[j])), w = 0.0;
            if(P[i].c == P[j].c) {
                w = dis * (double)(T[P[i].c]);
            } else {
                w = dis * (double)(t);
            }
            g[i][j] = g[j][i] = w;
        }
    }
    for(int k=1;k<=4*s;++k) {
        for(int i=1;i<=4*s;++i) {
            for(int j=1;j<=4*s;++j) {
                g[i][j] = min(g[i][j], g[i][k]+g[k][j]);
            }
        }
    }
    double ans = 0x3f3f3f;
    for(int i=1;i<=4*s;++i) {
        for(int j=1;j<=4*s;++j) {
            if(P[i].c==A && P[j].c==B) {
                ans = min(ans, g[i][j]);
            }
        }
    }
    printf("%.1lf",ans);
}
int main()
{
    n = read();
    while(n--) {
        work();
    }
    return 0;
}

PS:這我的的題解質量愈來愈差了

相關文章
相關標籤/搜索