POJ 1556 The Doors

来源:互联网 发布:拍照软件 桃心 编辑:程序博客网 时间:2024/05/16 05:50

题目:

http://poj.org/problem?id=1556

题意:

有一个10*10的图,其中可能存在一些墙,要求从(0,5)到(10,5)的最短距离,给出的墙位置是先给出一个横坐标x然后在这个位置上有y1,y2,y3,y4,其中有三堵墙0到y1,y2到y3,y4到10。

思路:

将所有墙的端点和起始点作为点建图。对于所有的墙存为线段,然后枚举所有点对组成的线段之间是否有线段相交,不向交则为两点间最短距离,然后求最短路就行了。

代码:

#define MAX 100007#define N 112int n,m;int flag,sum,ave,ans,res,len,ans1,ans2;double g[N][N];struct Point{    double x,y;}p[N];struct Line{    Point s,e;}l[N];double dis(Point p1,Point p2){    return sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));}double cross3(Point p0,Point p1,Point p2){    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}bool isMeet(Line l1,Line l2){    int mark=0;    double x=cross3(l1.s,l2.s,l2.e);    double y=cross3(l1.e,l2.s,l2.e);    if(!x||!y||x>0&&y<0||x<0&&y>0)mark++;    x=cross3(l2.s,l1.s,l1.e);    y=cross3(l2.e,l1.s,l1.e);    if(!x||!y||x>0&&y<0||x<0&&y>0)mark++;    if(mark==2)return true;    return false;}void floyd(int n){    for(int k=0;k<=n;k++)        for(int i=0;i<=n;i++)            for(int j=0;j<=n;j++)                g[i][j] = min(g[i][j],g[i][k]+g[k][j]);}int main(){    int i,j,k,T,cas;    double x,y1,y2,y3,y4,z;    while(scanf("%d",&n)!=EOF&&n!=-1)    {        for(i=0;i<N;i++)            for(j=0;j<N;j++)                g[i][j]=i!=j?MAX:0;        i=0;j=2;        p[0].x=0;p[0].y=5;        p[1].x=10;p[1].y=5;        while(n--)        {            scanf("%lf%lf%lf%lf%lf",&x,&y1,&y2,&y3,&y4);            l[i].s.x=x;l[i].s.y=0;l[i].e.x=x;l[i].e.y=y1;i++;            l[i].s.x=x;l[i].s.y=y2;l[i].e.x=x;l[i].e.y=y3;i++;            l[i].s.x=x;l[i].s.y=y4;l[i].e.x=x;l[i].e.y=10;i++;            p[j].x=x;p[j].y=y1;j++;            p[j].x=x;p[j].y=y2;j++;            p[j].x=x;p[j].y=y3;j++;            p[j].x=x;p[j].y=y4;j++;        }        for(int ii=0;ii<j;ii++)            for(int jj=0;jj<j;jj++)            {                Line t;                t.s=p[ii];t.e=p[jj];                flag=1;                for(k=0;k<i&&flag;k++)                {                    if(l[k].s.x==p[ii].x&&l[k].s.y==p[ii].y)continue;                    if(l[k].s.x==p[jj].x&&l[k].s.y==p[jj].y)continue;                    if(l[k].e.x==p[ii].x&&l[k].e.y==p[ii].y)continue;                    if(l[k].e.x==p[jj].x&&l[k].e.y==p[jj].y)continue;                    if(isMeet(l[k],t))flag=0;                }                if(flag)                    g[ii][jj]=min(g[ii][jj],dis(p[ii],p[jj]));            }        floyd(j);        printf("%.2lf\n",g[0][1]);    }    return 0;}





0 0
原创粉丝点击