zoukankan      html  css  js  c++  java
  • [Codeforces 32E] Hide-and-Seek

    Brief Intro:

    给两个人的坐标,一堵墙和一面镜子,询问两人能否看见对方

    Solution:

    一道以分类讨论为主的计算几何题,

    分别讨论两人坐标连线是否经过墙/镜子即可,

    难点在于如何求出点x关于线段[A,B]的对称点:

    point sym(point x,point A,point B){return 2*dot(A,B)/dot(B,B)*B-A+x;}

    以上给出一种方法:将线段[x,A]延长一倍,求出线段[x,x']的向量,再行加减即可

    Code:

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef complex<double> point;
    
    point a,b,w1,w2,m1,m2;
    
    point read(){double x,y;cin>>x>>y;return point(x,y);}
    double det(point a,point b){return imag(a*conj(b));}
    double dot(point a,point b){return real(a*conj(b));}
    bool on_seg(point x,point L,point R){return det(L-x,R-x)==0 && dot(L-x,R-x)<=0;}
    bool seg_cross(point a,point b,point c,point d)
    {
        double s1=det(c-a,b-a)*det(b-a,d-a);
        double s2=det(a-c,d-c)*det(d-c,b-c);
        if(s1<0 || s2<0) return false;
        if(s1==0 && s2==0) return on_seg(c,a,b) || on_seg(d,a,b);
        return true; 
    }
    point sym(point x,point A,point B){return 2*dot(A,B)/dot(B,B)*B-A+x;}
    
    bool check()
    {
        if(seg_cross(a,b,m1,m2))
            return !seg_cross(a,b,w1,w2) && det(b-a,m2-m1)==0;
        else if(seg_cross(a,b,w1,w2))
        {
            point A=sym(m1,a-m1,m2-m1),B=sym(m1,b-m1,m2-m1);
            return (seg_cross(a,B,m1,m2) && !seg_cross(a,B,w1,w2) && !seg_cross(A,b,w1,w2));
        }
        return true;
    }
    
    int main()
    {
        a=read();b=read();w1=read();w2=read();m1=read();m2=read();
        
        cout << (check()?"YES":"NO");
        return 0;
    }

    Review:

    1、求两线段是否有重合部分:

    先判相交,再判叉积是否为0

    2、判断一点是否在线段上:

    用叉积判是否在直线上,再用点积判线段两端是否在其两侧

  • 相关阅读:
    jquery从零开始(一)
    Android第三次作业
    Android第一次作业
    团队作业-项目答辩
    软工第二次作业
    软工团队第二次作业
    bug killer 团队
    软件工程第一次作业
    Android第四次作业
    Android第三次作业
  • 原文地址:https://www.cnblogs.com/newera/p/9094568.html
Copyright © 2011-2022 走看看