zoukankan      html  css  js  c++  java
  • POJ 3304 Segments (叉乘判断线段相交)

    <题目链接>

    题目大意:

    给出一些线段,判断是存在直线,使得该直线能够经过所有的线段。、

    解题思路:

    如果有存在这样的直线,过投影相交区域作直线的垂线,该垂线必定与每条线段相交,问题转化为问是否存在一条线和所有线段相交。

    如果存在这么一条直线,那么该直线一定能够移成经过两个端点的形式。枚举所有线段的两个端点,判断该直线和所有线段是否相交即可。
    #include <iostream>
    #include <math.h>
    #include <cstdio>
    using namespace std;
    #define MAXM 110
    #define EPS 1e-8    //10的负8次方
    
    typedef struct{
        double x1,y1,x2,y2;
    }Segment;   //线段
    
    Segment segment[MAXM];
    int n;
    
    double distance(double x1,double y1,double x2,double y2){        //计算两点之间距离
        return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
    }
    
    double corss(double x1,double y1,double x2,double y2,double x,double y){
        return (x2-x1)*(y-y1)-(x-x1)*(y2-y1);         //返回  (x2-x1,y2-y1) , (x-x1,y-y1)这两个向量的叉乘
    }    //根据的是(x,y)叉乘(b.x,b.y)=(x*b.y-y*b.x)公式;这个公式也可以通过三维向量叉乘的行列式得到,只不过要将这两个向量的Z坐标看成0
    
    bool judge(double x1,double y1,double x2,double y2){
        int i;
        if(distance(x1,y1,x2,y2)<EPS) return 0;
        for(i=0;i<n;i++){                  //之所以是>ERS(ERS为无穷小),是因为若当前线段有一个端点是该分割线段的一个端点,此时答案应该是0,然而实际上0也是可以的,所以将ERS设为无穷小
            if(corss(x1,y1,x2,y2,segment[i].x1,segment[i].y1)*corss(x1,y1,x2,y2,segment[i].x2,segment[i].y2)>EPS) return 0;
            //判断segment线段的两个端点是否置于该直线的两端
        }
        return 1;
    }
    
    int main(){
        int t,i,j,flag;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            for(i=0;i<n;i++)
                scanf("%lf%lf%lf%lf",&segment[i].x1,&segment[i].y1,&segment[i].x2,&segment[i].y2);
            if(n==1) {printf("Yes!
    ");continue;}
    
            flag=0;
            for(i=0;i<n && !flag;i++){
                for(int j=i+1;j<n && !flag;j++){              //以任意两条线段的两个端点构成分割线,只要任意一条这样的分割线能够经过每一条线段,那么输出Yes
                    if(judge(segment[i].x1,segment[i].y1,segment[j].x1,segment[j].y1) ||
                        judge(segment[i].x1,segment[i].y1,segment[j].x2,segment[j].y2) ||
                        judge(segment[i].x2,segment[i].y2,segment[j].x1,segment[j].y1) ||
                        judge(segment[i].x2,segment[i].y2,segment[j].x2,segment[j].y2))
                        flag=1;
                }
            }
            if(flag) printf("Yes!
    ");
            else printf("No!
    ");
        }
        return 0;
    }

    2018-08-01

  • 相关阅读:
    jQuery Easing 动画效果扩展
    【百度地图】标注点的动画效果
    CSS3制作404立体字体
    最长上升子序列的回溯 ZOJ 2432
    HDU 1423 最长上升公共子序列(LCIS)
    HDU 1114 完全背包问题的转化
    HDU 1085 多重背包转化为0-1背包问题
    opengl 对投影变化函数的理解
    HDU 1081 DP找最大和的矩阵
    HDU 1274 递归拼接字符串
  • 原文地址:https://www.cnblogs.com/00isok/p/9404631.html
Copyright © 2011-2022 走看看