UVa 393 The Doors <计算几何+最短路>

题目

题目大意:在一个正方形的小室中,有一些障碍墙(0到18个),每个障碍墙有两扇门允许通过,你的目标是找到起点( x=0,y=5 )到终点( x=10,y=5 )的最短路径。

分析:这是ljr《算法艺术与信息学竞赛》p.354的一道例题,书中给
出的解法是将这道题转化成图论中的最短路问题。将起点、终点以及所有门的两个边界点看做节点,两个点之间若可以直达,则在其所代表的的节点间加一条边(边权为点之间的距离)。

这道题我在网上居然没有找到题解。。只好自己做了,代码很丑,不过还好过了。

代码

#include <iostream>
#include <algorithm>
#include <iomanip>
#include <cmath>
#include <cstring>
using namespace std;

const double precision=1e-7;
const double INF=999999.0;

struct Wall{
    double x;
    double y[4];
};
struct Point{
    Point(double _x,double _y){
        x=_x;
        y=_y;
    }
    double x,y;
};

Point start(0,5);
Point endp(10,5);
Wall wall[20];
double map[100][100];
double dist[100];
bool vis[100];
int n;

double dis(Point& a,Point& b){
    double dx=b.x-a.x,dy=b.y-a.y;
    return sqrt(dx*dx+dy*dy);
}

int dlbcmp(double x){
    return fabs(x)<precision?0:(x>0?1:-1);
}

double det(double x1,double y1,double x2,double y2){
    return x1*y2-x2*y1;
}

double cross(Point a,Point b,Point c){
    return det(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y);
}

bool check(Point a,Point b,Point c,Point d){
    return (dlbcmp(cross(a,b,c))^dlbcmp(cross(a,b,d)))==-2&&
           (dlbcmp(cross(c,d,a))^dlbcmp(cross(c,d,b)))==-2;
}

void subBuild(Point p,int id,int j){
    int i=(id-1)/4;
    int k=id?i+1:0;
    if(j==n){
        for(;k<j;++k){
            if( check(p,endp,Point(wall[k].x,0),Point(wall[k].x,wall[k].y[0]))||
                check(p,endp,Point(wall[k].x,wall[k].y[1]),Point(wall[k].x,wall[k].y[2]))||
                check(p,endp,Point(wall[k].x,wall[k].y[3]),Point(wall[k].x,10)))
                    break;
        }
        if(k==j) map[id][4*n+1]=dis(p,endp);
    }
    else{
        int temp=k;
        for(int t=0;t<4;++t){
            Point node(wall[j].x,wall[j].y[t]); 
            for(k=temp;k<j;++k){
                if( check(p,node,Point(wall[k].x,0),Point(wall[k].x,wall[k].y[0]))||
                    check(p,node,Point(wall[k].x,wall[k].y[1]),Point(wall[k].x,wall[k].y[2]))||
                    check(p,node,Point(wall[k].x,wall[k].y[3]),Point(wall[k].x,10)))
                        break;
            }
            if(k==j) map[id][4*j+1+t]=dis(p,node);
        }
    }
}

void build(){
    int N=4*n+2;
    for(int i=0;i<N;++i){
        for(int j=0;j<N;++j){
            map[i][j]=INF;
        }
    }
    for(int i=0;i<=n;++i){
        subBuild(start,0,i);
    }
    for(int i=0;i<n;++i){
        for(int j=i+1;j<=n;++j){
            for(int k=0;k<4;++k){
                subBuild(Point(wall[i].x,wall[i].y[k]),4*i+1+k,j);
            }
        }
    }
}

void solve(){
    int N=4*n+2;
    memset(vis,false,sizeof vis);
    for(int i=1;i<N;++i){
        dist[i]=map[0][i];
    }
    dist[0]=0;
    for(int i=1;i<N;++i){
        double min_dist=INF;
        int p;
        for(int j=1;j<N;++j){
            if(dist[j]<min_dist&&(!vis[j])){
                min_dist=dist[p=j];
            }
        }
        vis[p]=true;
        for(int i=1;i<N;++i){
            if(!vis[i]){
                dist[i]=min(dist[p]+map[p][i],dist[i]);
            }
        }
    }
    cout<<fixed<<setprecision(2)<<dist[N-1]<<endl;
}

int main(){
    ios::sync_with_stdio(false);
    while(cin>>n,n!=-1){
        for(int i=0;i<n;++i){
            cin>>wall[i].x;
            for(int j=0;j<4;++j){
                cin>>wall[i].y[j];
            }
        }
        build();
        solve();
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
按下表要求布置拓扑,并配置 Web 服务器(index.html 代码已给出)。访问 Web 服 务器,单击“点此调用 javascript 方法”按钮。 设备名称 端口 IP 地址 默认网关 Fa0/0 192.168.1.254/24路由器 R0 Fa0/1 192.168.2.1/24 路由器 R1 Fa0/0 192.168.3.254/24 Fa0/1 192.168.2.2/24 PC0 Fa0 192.168.1.1/24 192.168.1.254 HTTP server Fa0 192.168.3.1/24 192.168.3.254/24 index.html 代码 <html> <center><font size='+2' color='blue'> Cisco Packet Tracer</font></center> <hr>Welcome to Cisco Packet Tracer. Opening doors to new opportunities. Mind Wide Open. <p>Quick Links: <br><a href='helloworld.html'>A small page</a> <br><a href='copyrights.html'>Copyrights</a> <br><a href='image.html'>Image page</a> <br><a href='cscoptlogo177x111.jpg'>Image</a> <br><br> <b>Testing HTML pages with Javascript and Stylesheet</b> <ul> <li><button type="button" onclick="myFunction()">点此调用javascript方法</button> <script> function myFunction() { alert ("兄 der, 调用成功!"); } </script> <li><a href="index2.html">HTML page with an external javascript file (index2.html) </a> <li><a href="index3.html">HTML page with an external stylesheet file (index3.html) </a> <li><a href="index4.html">HTML page with both external javascript and stylesheet files (index4.html) </a> <li><a href='image.html'>Image page: Test for a previously saved file with the image file in the directory of the pkt file</a> <li><a href='image2.html'>Image page: Test for with the image file imported in the PT Server</a> </html>
最新发布
05-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值