首页 > 代码库 > poj 2074 Line of Sight 计算几何

poj 2074 Line of Sight 计算几何

  1 /**
  2 大意:给定一个建筑--水平放置,给定n个障碍物, 给定一条街道,从街道上能看到整个建筑的最长的连续的区域
  3 思路: 分别确定每一个障碍物所确立的盲区,即----建筑物的终点与障碍物的起点的连线,建筑物的起点与障碍物的终点的连线。。这段区域即为盲区,,,有多个盲区,需要去重。。
  4 学习之处: 1、障碍物在输入时去重,非常巧妙
  5                    2、 盲区的去重。与重组,。。巧妙。。
  6                     3、 寻找最大连续区域,,
  7 **/
  8 #include <iostream>
  9 #include <cstdio>
 10 #include <algorithm>
 11 using namespace std;
 12 const double eps = 1e-8;
 13 double  max(double  a,double b){
 14     return a>b?a:b;
 15 }
 16 
 17 struct point{
 18     double x,y;
 19 };
 20 
 21 struct segment{
 22     point s,e;
 23 };
 24 
 25 struct line{
 26     double a,b,c;
 27 };
 28 
 29 struct data{
 30     double l,r;
 31 }a[100];
 32 
 33 line getline(point p1,point p2){
 34     line tmp;
 35     tmp.a = p1.y-p2.y;
 36     tmp.b = p2.x-p1.x;
 37     tmp.c = p1.x*p2.y-p2.x*p1.y;
 38     return tmp;
 39 }
 40 
 41 double getInterx(line l1,line l2){
 42     return (l1.b*l2.c-l2.b*l1.c)/(l1.a*l2.b-l2.a*l1.b);
 43 }
 44 
 45 bool cmp(data a,data b){
 46     return a.l<b.l;
 47 }
 48 
 49 int main()
 50 {
 51     int n,i,j;
 52     double x1,x2,y;
 53     segment hou,pro,obs[100];
 54     while(cin>>x1>>x2>>y){
 55         if(x1==0&&x2==0&&y==0)
 56             break;
 57         hou.s.x = x1,hou.s.y = y;
 58         hou.e.x = x2,hou.e.y = y;
 59         cin>>x1>>x2>>y;
 60         pro.s.x = x1,pro.s.y = y;
 61         pro.e.x = x2,pro.e.y = y;
 62         cin>>n;
 63         for(i=0;i<n;i++){
 64             cin>>x1>>x2>>y;
 65             obs[i].s.x = x1,obs[i].s.y = y;
 66             obs[i].e.x = x2,obs[i].e.y =y;
 67             if(y>hou.s.y||y<pro.s.y){
 68                 n--;
 69                 i--;
 70             }
 71         }
 72         line l_pro = getline(pro.s,pro.e);
 73         for(i=j=0;i<n;i++,j++){
 74             line l1,l2;
 75             l1 = getline(hou.s,obs[i].e);
 76             l2 = getline(hou.e,obs[i].s);
 77             a[j].r = getInterx(l_pro,l1);
 78             a[j].l = getInterx(l_pro,l2);
 79             if(a[j].r<pro.s.x||a[j].l>pro.e.x){
 80                 j--;
 81                 continue;
 82             }
 83             if(a[j].l<pro.s.x)     //对于盲区超出街道的区域。
 84                 a[j].l = pro.s.x;
 85             if(a[j].r>pro.e.x)
 86                 a[j].r = pro.e.x;
 87         }
 88         n = j;
 89         if(n==0){     //若没有障碍物在建筑物与街道之间,,则输出整个街道的长度
 90             printf("%.2lf\n",pro.e.x-pro.s.x);
 91             continue;
 92         }
 93         sort(a,a+n,cmp);
 94         double l[100],r[100];
 95         l[0] = a[0].l,r[0] = a[0].r;
 96         for(j=0,i=1;i<n;i++){     //盲区的重组与去重
 97             if(r[j]<a[i].l){
 98                 j++;
 99                 l[j] = a[i].l;
100                 r[j] = a[i].r;
101             }else
102             r[j] = max(r[j],a[i].r);
103         }
104         double ans = max(l[0]-pro.s.x,pro.e.x-r[j]);          //寻找最大值。
105         for(i=0;i<j;i++){
106             ans = max(ans,l[i+1]-r[i]);
107         }
108         if(ans<eps)
109             printf("No View\n");
110         else
111             printf("%.2lf\n",ans);
112     }
113     return 0;
114 }