zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    SpringMVC:拦截器拦截时机和原理
    SpringBoot:MessageConverter自动配置原理
    SpringMVC:返回值处理器原理和MessageConverter原理
    SpringMVC:自定义Converter
    XML-RPC协议学习
    ContentControl 与 ViewModel (一)
    C# 获取相对路径(绝对路径转相对路径)
    WPF 最简单的TextBox水印
    WPF/Silverlight开发的15个最佳实践(转发)
    WPF 打印崩溃问题( 异常:Illegal characters in path/路径中有非法字符)
  • 原文地址:https://www.cnblogs.com/shangyu/p/3804001.html
Copyright © 2011-2022 走看看