• POJ 3304 Segments【叉积】


    题意:有n条线段,问有没有一条直线使得所有线段在这条直线上的投影至少有一个共同点。

    思路:逆向思维,很明显这个问题可以转化为是否有一条直线穿过所有线段,若有,问题要求的直线与该直线垂直,并且公共点为垂足。

    因此只需要枚举每两个端点形成的直线,判断是否和所有线段相交。证明,若存在一条与所有线段相交的直线L,则可以将L平移直到再移动就不满足"与所有线段相交"这个条件时,此时L经过某个线段的一个端点,再将L旋转直到再旋转就不满足“与所有线段相交"这个条件时,肯定与另一个端点相交。

    判断直线与线段相交可以用

    1,叉积的性质,若线段与直线相交,则线段两个端点在直线的两边,设t1为一端与直线的叉积,t2为另一端与直线的叉积,线段与直线相交时,t1 X t2<=0

    2,设线段所在的直线为tmp,求L与tmp的交点p,若线段两端点到p的距离之和等于线段的长度,则线段与直线相交

    坑点:

    1,n=1时需要特判。

    2,当选择的两个点重合时,会导致所有点与该直线的叉积一直小于0从而认为各个线段和该直线相交。

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    struct point{
        double x,y;
        point(){}
        point(double x_,double y_){
            x=x_,y=y_;
        }
        point operator -(const point &b)const{
            return point(x-b.x,y-b.y);
        }
        double operator *(const point &b)const{//点积 
            return x*b.x+y*b.y;
        }
        double operator ^(const point &b)const{//叉积 
            return x*b.y-y*b.x;
        }
    };
    double cal(point p0,point p1,point p2){//小于0表示在p1处左折,大于0右折,等于0同线 
        return (p1-p0)^(p2-p0);
    }
    const int N=111;
    const double esp=1e-8;
    point s[N],e[N];
    int n;
    int pd(point a,point b){
        if(fabs(a.x-b.x)<esp&&fabs(a.y-b.y)<esp)
            return 0;
        for(int i=1;i<=n;i++){
            if(cal(s[i],a,b)*cal(e[i],a,b)>esp)
                return 0;
        }
        return 1;
    }
    int main(){
        int t,i,j;
        scanf("%d",&t);
        while(t--){
            scanf("%d",&n);
            for(i=1;i<=n;i++){
                scanf("%lf%lf%lf%lf",&s[i].x,&s[i].y,&e[i].x,&e[i].y);
            }
            int f=0;
            if(n<2)    f=1;
            for(i=1;i<=n&&!f;i++){
                for(j=i+1;j<=n&&!f;j++){
                    if(pd(s[i],s[j]))    f=1;
                    if(pd(s[i],e[j]))    f=1;
                    if(pd(e[i],s[j]))    f=1;
                    if(pd(e[i],e[j]))    f=1;
                }
            }
            if(f)    puts("Yes!");
            else    puts("No!"); 
        }
        return 0;
    }

    http://blog.sina.com.cn/s/blog_6635898a0100n2lv.html

    http://www.cnblogs.com/staginner/archive/2012/02/07/2340835.html

      

  • 相关阅读:
    Attribute特性 与 Reflection反射技术
    星星评分控件----------WebForm服务器控件开发系列
    CheckBox美化控件----------WinForm控件开发系列
    RadioButton美化控件----------WinForm控件开发系列
    分割线控件----------WinForm控件开发系列
    mysql数据库中自增ID不自增1的解决办法
    [WPF] 操作DataGrid单元格
    [WPF] DataGrid单元格中的TextBox绑定数据源
    WPF中同类型实体间的消息推送
    C#获取屏幕工作区大小
  • 原文地址:https://www.cnblogs.com/L-King/p/5727086.html
Copyright © 2020-2023  润新知