poj1039Pipe(直线交点、叉积)

链接

之前刷poj计划时刷过,不过也没什么印象了。打铁还是趁热,还没热起来就放弃了,前面算是做了无用功,有如胡乱的看解题报告一样。

 题目应该是比较经典的集合入门题,黑书上有一部分核心讲解。

题目中的最优光线必是要经过端点,这个黑书上提到了,应该也可以想到,然后就可以枚举一上一下的端点,判断它最长能走到哪里,首先可以判断出它是否能进的去第i个入口,

这个可以通过叉积进行判断上下点是不是在这条光线异侧,然后求直线的交点。

有一份好的模板很重要~

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 55
 12 #define LL long long
 13 #define INF 0xfffffff
 14 const double eps = 1e-8;
 15 const double pi = acos(-1.0);
 16 const double inf = ~0u>>2;
 17 struct Point
 18 {
 19     double x,y;
 20     Point(double x=0,double y=0):x(x),y(y) {} //构造函数 方便代码编写
 21 }p[N];
 22 typedef Point pointt;
 23 pointt operator + (Point a,Point b)
 24 {
 25     return Point(a.x+b.x,a.y+b.y);
 26 }
 27 pointt operator - (Point a,Point b)
 28 {
 29     return Point(a.x-b.x,a.y-b.y);
 30 }
 31 pointt operator * (Point a,double b)
 32 {
 33     return Point(a.x*b,a.y*b);
 34 }
 35 pointt operator / (Point a,double b)
 36 {
 37     return Point(a.x/b,a.y/b);
 38 }
 39 bool operator < (const Point &a,const Point &b)
 40 {
 41     return a.x<b.x||(a.x==b.x&&a.y<b.y);
 42 }
 43 int dcmp(double x)
 44 {
 45     if(fabs(x)<eps) return 0;
 46     else return x<0?-1:1;
 47 }
 48 bool operator == (const Point &a,const Point &b)
 49 {
 50     return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
 51 }
 52 //求点积以及利用点积求长度和夹角的函数
 53 double dot(Point a,Point b)
 54 {
 55     return a.x*b.x+a.y*b.y;
 56 }
 57 double cross(Point a,Point b,Point c)//差乘判左右 a->b与a->c向量的关系
 58 {
 59     return (a.x-c.x)*(a.y-b.y)-(a.y-c.y)*(a.x-b.x);
 60 }
 61 bool intersection1(Point p1, Point p2, Point p3, Point p4, Point& p)      // 直线相交
 62 {
 63     double a1, b1, c1, a2, b2, c2, d;
 64     a1 = p1.y - p2.y;
 65     b1 = p2.x - p1.x;
 66     c1 = p1.x*p2.y - p2.x*p1.y;
 67     a2 = p3.y - p4.y;
 68     b2 = p4.x - p3.x;
 69     c2 = p3.x*p4.y - p4.x*p3.y;
 70     d = a1*b2 - a2*b1;
 71     if (!dcmp(d))    return false;
 72     p.x = (-c1*b2 + c2*b1) / d;
 73     p.y = (-a1*c2 + a2*c1) / d;
 74     return true;
 75 }
 76 int main()
 77 {
 78     int n,i,j,g;
 79     while(scanf("%d",&n)&&n)
 80     {
 81         for(i  = 1; i <= n ; i++)
 82         {
 83             scanf("%lf%lf",&p[i].x,&p[i].y);
 84             p[i+n].x = p[i].x;
 85             p[i+n].y = p[i].y-1.0;
 86         }
 87         double ans  = -INF;
 88         int flag = 0;
 89         for(i = 1 ; i <= n; i++)
 90         {
 91             for(j = n+1 ; j <= 2*n ; j++)
 92             {
 93                 if(j==n+i) continue;
 94                 Point sg ;
 95                 for(g = 1; g <= n ; g++)
 96                 {
 97                     int d1 = dcmp(cross(p[i],p[j],p[g]));
 98                     int d2 = dcmp(cross(p[i],p[j],p[g+n]));
 99                     if(g==1&&d1*d2<=0) continue;
100                     if(g==1&&d1*d2>0) break;
101                     if(d1*d2>0)
102                     {
103                         if(intersection1(p[i],p[j],p[g-1],p[g],sg))
104                         {
105                             ans = max(ans,sg.x);
106                         }
107                         if(intersection1(p[i],p[j],p[n+g-1],p[n+g],sg))
108                         {
109                             ans = max(ans,sg.x);
110                         }
111                         break;
112                     }
113                 }
114                 if(g>n)
115                 {
116                     flag = 1;
117                     break;
118                 }
119             }
120             if(flag) break;
121         }
122         if(flag) puts("Through all the pipe.");
123         else printf("%.2f
",ans);
124     }
125     return 0;
126 }
View Code
原文地址:https://www.cnblogs.com/shangyu/p/3804001.html