• POJ 3304


    题目可以转化成是否存在这样的一条直线,穿过所有的线段。这是很容易就能想到的。

    然后,假如只有一个端点重合,那么我们可以知道,必定会有属于两条线段的某两个端点连出的直线可以穿过所有线段。这是枚举的思想。

    那么,我们该怎么判定直线与线段有交点呢?不妨通过跨立的定义来做,这是经人点醒了才想到的。

    在求线段是否有交点的时候用到过跨立,但我认为,跨立的定义应该是延长的线后是否存在交点(当前包括开始就存在交点的。)

    假设枚举两点得到的线段是A1A2,判断是否有交点的线段是B1B2,则要求A1A2跨立B1B2。

    设P1=向量(O->B1),P2=(O->B2),Q1=(O->A1),Q2=(O->A2);

    则((P1-Q1)x(Q2-Q1))*((Q1-P2)x(Q2-Q1))>=0

     1 #include <iostream>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <cstdio>
     5 #include <math.h>
     6 #define eps 0.00000001
     7 using namespace std;
     8 
     9 typedef struct po{
    10     double x,y;
    11 }Point;
    12 
    13 typedef struct pl{
    14     Point start,end;
    15 }Pleg;
    16 int how_point,how_pleg;
    17 Point pot[300];
    18 Pleg peg[300];
    19 Pleg Line;
    20 
    21 bool dbcmp(double x,double y){
    22     if(fabs(x-y)<eps) return false;
    23     return true;
    24 }
    25 
    26 double multi(Point a,Point b, Point c,Point d){
    27     return (a.x-b.x)*(c.y-d.y)-(a.y-b.y)*(c.x-d.x);
    28 }
    29 
    30 bool slove(int k){
    31     if(multi(peg[k].start,Line.start,Line.end,Line.start)*multi(Line.start,peg[k].end,Line.end,Line.start)>=0)
    32     return true;
    33     return false;
    34 }
    35 
    36 int main(){
    37     int T,n;
    38     scanf("%d",&T);
    39     while(T--){
    40         how_point=how_pleg=0;
    41         scanf("%d",&n);
    42         for(int i=1;i<=n;i++){
    43             scanf("%lf%lf",&pot[how_point].x,&pot[how_point].y);
    44             peg[how_pleg].start=pot[how_point];
    45             how_point++;
    46             scanf("%lf%lf",&pot[how_point].x,&pot[how_point].y);
    47             peg[how_pleg].end=pot[how_point];
    48             how_point++;
    49             how_pleg++;
    50         }
    51         bool flag=false;
    52         for(int i=0;i<how_point;i++){
    53             for(int j=i+1;j<how_point;j++){
    54                 if(!dbcmp(pot[i].x,pot[j].x)&&!dbcmp(pot[i].y,pot[j].y))
    55                 continue;
    56                 Line.start=pot[i]; Line.end=pot[j];
    57                 int k;
    58                 for(k=0;k<how_pleg;k++){
    59                     if(slove(k)){
    60                         continue;
    61                     }
    62                     break;
    63                 }
    64                 if(k==how_pleg){
    65                     flag=true;
    66                     break;
    67                 }
    68             }
    69             if(flag) break;
    70         }
    71         if(flag) printf("Yes!
    ");
    72         else printf("No!
    ");
    73     }
    74     return 0;
    75 }
    View Code
  • 相关阅读:
    Java-继承,多态练习09-22-01
    Java-类与类之间的关系
    Java-继承 共3题
    设计模式-访问者模式
    设计模式-策略模式
    JAVA-初步认识-常用对象API(集合框架-List常用子类的特点)
    JAVA-初步认识-常用对象API(集合框架-ListIterator接口)
    JAVA-初步认识-常用对象API(集合框架-List集合的常用方法)
    JAVA-初步认识-常用对象API(集合框架-List和Set的特点)
    JAVA-初步认识-常用对象API(集合框架-迭代器的原理)
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/3865954.html
Copyright © 2020-2023  润新知