强墙

描述

在一个长宽均为10,入口出口分别为(0,5)、(10,5)的房间里,有几堵墙,每堵墙上有两个缺口,求入口到出口的最短路经。

图片

格式

输入格式

第一排为n(n<=20),墙的数目。

接下来n排,每排5个实数x,a1,b1,a2,b2。

x表示墙的横坐标(所有墙都是竖直的),a1-b1和a2-b2之间为空缺。

a1、b1、a2、b2保持递增,x1-xn也是递增的。

输出格式

输出最短距离,保留2位小数。

样例1

样例输入1

2
4 2 7 8 9
7 3 4.5 6 7

样例输出1

10.06

来源

Tsuzuki Matsumoto 
From ZJU

 

N^3DP

最短路径肯定会经过一个端点,那么就枚举端点,然后判断中间是否可以连通就好了

貌似因为精度问题WA了一个点

解决方法就是不要用斜率,改成乘法就好了。。然而不想改了。。。

  1 #include<bits/stdc++.h>
  2 #define inf 1000000000
  3 #define maxn 20+5
  4 #define maxm 5000000+5
  5 #define eps 1e-6
  6 #define ll long long
  7 #define mod 5000011
  8 #define for0(i,n) for(int i=0;i<=(n);i++)
  9 #define for1(i,n) for(int i=1;i<=(n);i++)
 10 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 11 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 12 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
 13 using namespace std;
 14 int read(){
 15     int x=0,f=1;char ch=getchar();
 16     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 17     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
 18     return x*f;
 19 }
 20 struct wal{
 21     double x,a[3],b[3];
 22 }s[maxn];
 23 double f[maxn][6];
 24 int n;
 25 double fabs(double x){
 26     if(x<0)return -x;
 27     return x;
 28 }
 29 bool judge(double x,int j,double y1,double x1){
 30     for1(i,2){
 31         double k1=(y1-s[j].a[i])/(x1-s[j].x);
 32         double k2=(y1-s[j].b[i])/(x1-s[j].x);
 33         if(k2<x&&x<k1)return 1;
 34         double t1=fabs(k1-x),t2=fabs(k2-x);
 35         if(t1<=eps||t2<=eps)return 1;
 36     }
 37     return 0;
 38 }
 39 double cal(double y1,double x1,double y2,double x2){
 40     double t1=y2-y1,t2=x2-x1;
 41     return sqrt(t1*t1+t2*t2);
 42 }
 43 int main(){
 44     //freopen("input.txt","r",stdin);
 45     //freopen("output.txt","w",stdout);
 46     n=read();
 47     int fl=0;
 48     for1(i,n){
 49         cin>>s[i].x>>s[i].a[1]>>s[i].b[1]>>s[i].a[2]>>s[i].b[2];
 50         if(s[i].b[1]<=5&&5<=s[i].a[1])fl++;
 51         if(s[i].b[2]<=5&&5<=s[i].a[2])fl++;
 52     }
 53     if(fl==n){
 54         printf("10.00");
 55         return 0;
 56     }
 57     for1(i,n)
 58         for1(j,5)
 59             f[i][j]=inf;
 60     f[1][1]=cal(s[1].a[1],s[1].x,5,0);
 61     f[1][2]=cal(s[1].b[1],s[1].x,5,0);
 62     f[1][3]=cal(s[1].a[2],s[1].x,5,0);
 63     f[1][4]=cal(s[1].b[2],s[1].x,5,0);
 64     for2(i,2,n)
 65         for1(c,2){
 66             for2(j,1,i-1)
 67                 for1(cc,2){
 68                     double k1=(s[i].a[c]-s[j].a[cc])/(s[i].x-s[j].x);
 69                     double k2=(s[i].a[c]-s[j].b[cc])/(s[i].x-s[j].x);
 70                     double k3=(s[i].b[c]-s[j].a[cc])/(s[i].x-s[j].x);
 71                     double k4=(s[i].b[c]-s[j].b[cc])/(s[i].x-s[j].x);
 72                     int flag1=0,flag2=0,flag3=0,flag4=0;
 73                     for2(k,j+1,i-1){
 74                         if(!judge(k1,k,s[i].a[c],s[i].x))flag1=1;
 75                         if(!judge(k2,k,s[i].a[c],s[i].x))flag2=1;
 76                         if(!judge(k3,k,s[i].b[c],s[i].x))flag3=1;
 77                         if(!judge(k4,k,s[i].b[c],s[i].x))flag4=1;
 78                         if(flag1+flag2+flag3+flag4==4)break;
 79                     }
 80                     if(!flag1)f[i][1+(c-1)*2]=min(f[i][1+(c-1)*2],f[j][1+(cc-1)*2]+cal(s[i].a[c],s[i].x,s[j].a[cc],s[j].x));
 81                     if(!flag2)f[i][1+(c-1)*2]=min(f[i][1+(c-1)*2],f[j][2+(cc-1)*2]+cal(s[i].a[c],s[i].x,s[j].b[cc],s[j].x));
 82                     if(!flag3)f[i][2+(c-1)*2]=min(f[i][2+(c-1)*2],f[j][1+(cc-1)*2]+cal(s[i].b[c],s[i].x,s[j].a[cc],s[j].x));
 83                     if(!flag4)f[i][2+(c-1)*2]=min(f[i][2+(c-1)*2],f[j][2+(cc-1)*2]+cal(s[i].b[c],s[i].x,s[j].b[cc],s[j].x));
 84                 }
 85             double k1=(s[i].a[c]-5)/(s[i].x);
 86             double k2=(s[i].b[c]-5)/(s[i].x);
 87             int flag1=0,flag2=0;
 88             for1(k,i-1){
 89                 if(!judge(k1,k,s[i].a[c],s[i].x))flag1=1;
 90                 if(!judge(k2,k,s[i].b[c],s[i].x))flag2=1;
 91                 if(flag1+flag2==2)break;
 92             }
 93             if(!flag1)f[i][1+(c-1)*2]=min(f[i][1+(c-1)*2],cal(s[i].a[c],s[i].x,5,0));
 94             if(!flag2)f[i][2+(c-1)*2]=min(f[i][2+(c-1)*2],cal(s[i].b[c],s[i].x,5,0));
 95         }
 96     double ans=inf;
 97     for1(j,n)
 98         for1(cc,2){
 99             double k1=(5-s[j].a[cc])/(10-s[j].x);
100             double k2=(5-s[j].b[cc])/(10-s[j].x);
101             int flag1=0,flag2=0;
102             for2(k,j+1,n){
103                 if(!judge(k1,k,5,10))flag1=1;
104                 if(!judge(k2,k,5,10))flag2=1;
105                 if(flag1+flag2==2)break;
106             }
107             if(!flag1)ans=min(ans,f[j][1+(cc-1)*2]+cal(5,10,s[j].a[cc],s[j].x));
108             if(!flag2)ans=min(ans,f[j][2+(cc-1)*2]+cal(5,10,s[j].b[cc],s[j].x));
109         }
110     printf("%.2lf",ans);
111     return 0;
112 }
View Code

 

posted @ 2017-08-05 10:39  HTWX  阅读(207)  评论(0编辑  收藏  举报