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 }