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\n",ans);

124     }

125     return 0;

126 }
View Code

 

你可能感兴趣的:(poj)