• HDU 3492 (直线与所有线段相交) Segment


    题意:

    给出n个线段,判断是否存在一条直线使得所有线段在直线上的射影的交非空。

    分析:

    如果我们找到一条与所有线段相交的直线,然后做一条与该直线垂直的直线,这些线段在直线上的射影就一定包含这个垂足。

    所以我们只要判断是否存在一条直线与所有的点相交即可。

    如果存在这样一条直线,那么将这条直线平移或者旋转,就会被这些线段中的某两个端点“卡”住。

    所以我们枚举两个端点,然后判断这些线段是否与这两个点所在的直线都相交即可。

    本以为是一道很简单的计算几何,结果卡了好几天。

    看了别人的题解,才发现问题所在。

    http://www.cppblog.com/acronix/archive/2010/08/17/123765.html

    因为有可能存在重点,所以要判断,弄了个标志变量issame,如果所有的点都是同一个点那么也应该输出Yes

     1 #include <cstdio>
     2 #include <cmath>
     3 
     4 const int maxn = 600 + 10;
     5 const double eps = 1e-8;
     6 struct Point
     7 {
     8     double x, y;
     9     Point(double x=0, double y=0):x(x), y(y) {}
    10 }p[maxn];
    11 int dcmp(double x)
    12 {
    13     if(fabs(x) < eps) return 0;
    14     return x < 0 ? -1 : 1;
    15 }
    16 
    17 Point operator - (const Point& a, const Point& b)
    18 { return Point(a.x-b.x, a.y-b.y); }
    19 
    20 double Cross(const Point& a, const Point& b)
    21 { return (a.x*b.y - a.y*b.x); }
    22 
    23 bool operator == (const Point& a, const Point& b)
    24 { return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0; }
    25 
    26 bool intersect(const Point& a, const Point& b, const Point& p1, const Point& p2)
    27 {
    28     int d1 = dcmp(Cross(b-a, p1-a));
    29     int d2 = dcmp(Cross(b-a, p2-a));
    30     if(d1 == 0 || d2 == 0) return true;
    31     if(d1 * d2 < 0) return true;
    32     return false;
    33 }
    34 
    35 int main(void)
    36 {
    37     //freopen("3492in.txt", "r", stdin);
    38     int T;
    39     scanf("%d", &T);
    40     while(T--)
    41     {
    42         int n;
    43         scanf("%d", &n);
    44         for(int i = 0; i < 2*n-1; i += 2)
    45             scanf("%lf%lf%lf%lf", &p[i].x, &p[i].y, &p[i+1].x, &p[i+1].y);
    46         
    47         bool exist = false;
    48         bool issame = true;
    49         for(int i = 0; i < 2*n-1 && !exist; ++i)
    50         {
    51             for(int j = i+1; j < 2*n && !exist; ++j)
    52             {
    53                 if(p[i] == p[j]) continue;
    54                 issame = false;
    55                 int k;
    56                 for(k = 0; k < 2*n; k += 2)
    57                     if(!intersect(p[i], p[j], p[k], p[k+1])) break;
    58                 if(k == 2 * n)
    59                     exist = true;
    60             }
    61         }
    62         
    63         if(exist || issame) puts("Yes");
    64         else puts("No");
    65     }
    66     
    67     return 0;
    68 } 
    代码君
  • 相关阅读:
    JavaScript脚本的两种放置方式
    对象 属性 事件 方法
    媒体查询
    HTML5布局
    图像
    布局
    列表,表格,表单
    盒子
    vue.js常见面试题及常见命令介绍
    Winform读报工具
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4124942.html
Copyright © 2020-2023  润新知