zoukankan      html  css  js  c++  java
  • 最短路+线段交 POJ 1556 好题

      1 // 最短路+线段交 POJ 1556 好题
      2 // 题意:从(0,5)到(10,5)的最短距离,中间有n堵墙,每堵上有两扇门可以通过
      3 // 思路:先存图。直接n^2来暴力,不好写。分成三部分,起点 终点和之间的点:中间点之间:起点和终点的距离
      4 // n最大为18所以直接n^3最短路
      5 
      6 
      7 #include <cstdio>
      8 #include <cstring>
      9 #include <iostream>
     10 #include <algorithm>
     11 #include <map>
     12 #include <set>
     13 #include <queue>
     14 #include <stdlib.h>
     15 #include <cmath>
     16 using namespace std;
     17 typedef long long LL;
     18 const double inf = 1e9;
     19 const int N = 5000;
     20 const double eps = 1e-8;
     21 void fre() {freopen("in.txt","r",stdin);}
     22 
     23 int sgn(double x){
     24     if(fabs(x)<eps) return  0;
     25     if(x<0) return -1;
     26     return 1;
     27 }
     28 
     29 struct Point{
     30     double x,y;
     31     Point(){}
     32     Point(double _x,double _y){
     33         x=_x;y=_y;
     34     }
     35     Point operator -(const Point &b)const{
     36         return Point(x-b.x,y-b.y);
     37     }
     38     double operator *(const Point &b)const{
     39         return x*b.x+y*b.y;
     40     }
     41     double operator ^(const Point &b)const{
     42         return x*b.y-y*b.x;
     43     } 
     44 };
     45 
     46 struct Line{
     47     Point s,e;
     48     Line(){}
     49     Line(Point _s,Point _e){
     50         s=_s,e=_e;
     51     }
     52 };
     53 Line line[N];
     54 double xmult(Point p0,Point p1,Point p2){
     55     return (p1-p0)^(p2-p0);
     56 }
     57 
     58 double dist(Point a,Point b){
     59     return sqrt((a-b)*(a-b));
     60 }
     61 
     62 bool inter(Line l1,Line l2){
     63     return max(l1.s.x,l1.e.x)>=min(l2.s.x,l2.e.x)&&max(l2.s.x,l2.e.x)>=min(l1.s.x,l1.e.x)&&max(l1.s.y,l1.e.y)>=min(l2.s.y,l2.e.y)&&max(l2.s.y,l2.e.y)>=min(l1.s.y,l1.e.y)&&sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e))<=0&&sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e))<=0;
     64 }
     65 
     66 double d[100][100];
     67 int main(){
     68     // fre();
     69     int n;
     70     while(~scanf("%d",&n)){
     71         if(n==-1) break;
     72         // clc(d,
     73         for(int i=0;i<=4*n+1;i++){
     74             for(int j=0;j<=4*n+1;j++){
     75                 if(i==j) d[i][j]=0;
     76                 else d[i][j]=inf;
     77             }
     78         }
     79         for(int i=1;i<=n;i++){
     80             double x,y3,y1,y4,y2;
     81             scanf("%lf%lf%lf%lf%lf",&x,&y1,&y2,&y3,&y4);
     82             line[i*2-1]=Line(Point(x,y1),Point(x,y2));
     83             line[i*2]=Line(Point(x,y3),Point(x,y4));
     84         }
     85         bool flag;
     86         for(int i=1;i<=4*n;i++){
     87             flag=true;
     88             int cn=(i+3)/4;
     89             Point tem;
     90             if(i&1) tem=line[(i+1)/2].s;
     91             else tem=line[(i+1)/2].e;
     92             for(int j=1;j<cn;j++){
     93                 if(inter(line[j*2-1],Line(Point(0,5),tem))==false&&inter(line[j*2],Line(Point(0,5),tem))==false){
     94                     flag=false;
     95                     break;
     96                 }
     97             }
     98             if(flag) d[0][i]=d[i][0]=dist(Point(0,5),tem);
     99             flag=true;
    100             for(int j=cn+1;j<=n;j++){
    101                 if(inter(line[j*2-1],Line(Point(10,5),tem))==false&&inter(line[j*2],Line(Point(10,5),tem))==false){
    102                     flag=false;
    103                     break;
    104                 }
    105             }
    106             if(flag) d[4*n+1][i]=d[i][4*n+1]=dist(Point(10,5),tem);
    107         }
    108         flag=true;
    109         for(int i=1;i<=4*n;i++){
    110             for(int j=i+1;j<=4*n;j++){
    111                flag=true;
    112                Point p1,p2;
    113                int cn1,cn2;
    114                cn1=(i+3)/4;
    115                cn2=(j+3)/4;
    116                if(i&1) p1=line[(i+1)/2].s;
    117                else p1=line[(i+1)/2].e;
    118                if(j&1) p2=line[(j+1)/2].s;
    119                else p2=line[(j+1)/2].e;
    120                for(int cn=cn1+1;cn<cn2;cn++){
    121                     if(inter(line[cn*2-1],Line(p1,p2))==false&&inter(line[cn*2],Line(p1,p2))==false){
    122                       flag=false;
    123                       break;
    124                     }
    125                }
    126                if(flag) d[i][j]=d[j][i]=dist(p1,p2);
    127             }
    128         }
    129         flag=true;
    130         for(int i=1;i<=n;i++){
    131             if(inter(line[i*2-1],Line(Point(0,5),Point(10,5)))==false&&inter(line[i*2],Line(Point(0,5),Point(10,5)))==false){
    132                 flag=false;
    133                 break;
    134             }
    135         }
    136         if(flag) d[0][4*n+1]=d[4*n+1][0]=dist(Point(0,5),Point(10,5));
    137         for(int i=0;i<=4*n+1;i++){
    138             for(int j=0;j<=4*n+1;j++){
    139                 for(int k=0;k<=4*n+1;k++){
    140                     if(d[i][k]+d[k][j]<d[i][j]) d[i][j]=d[i][k]+d[k][j];
    141                 }
    142             }
    143         }
    144         printf("%.2f
    ",d[0][4*n+1]);
    145     }
    146     return 0;
    147 }
  • 相关阅读:
    两条斜线
    Cantor表
    城市网络
    一起来数二叉树吧
    牛客网音乐研究(枚举)
    删括号
    合并回文子串
    寻找道路
    EXTJS 4.0.2 XML数据
    extjs4.0.2a gridpanel看不到横向滚动条的一种原因
  • 原文地址:https://www.cnblogs.com/ITUPC/p/5851754.html
Copyright © 2011-2022 走看看