zoukankan      html  css  js  c++  java
  • 2017.10.1 国庆清北 D1T2 两个逗比捉迷藏

    题目描述

    你是能看到第二题的friends呢。

    ——laekov

    Hja和Yjq在玩捉迷藏。Yjq躲了起来,Hja要找他。在他们玩游戏的房间里,只有一堵不透明的墙和一个双面的镜子。Hja和Yjq可以看作平面上坐标分别为(xv,yv)和(xp,yp)的点。墙是一条连接(xw1,yw1)和(xw2,yw2)的线段,镜子是一条连接(xm1,ym1)和(xm2,ym2)的线段。

    如果视线和障碍物有公共点,那么我们认为视线会被阻挡,无法看见。如果视线和镜子有公共点,那么我们认为发生了反射。反射的过程遵循物理规律——入射角等于反射角,且反射光线与入射光线在镜子同侧。也就是说,想要看见对方,Hja和Yjq必须在镜子的同一侧,包括镜子所在直线上(参见样例1)。如果视线与镜子重合,那么不会发生反射,并且镜子不被当作障碍物(参见样例4)。

    Hja很想知道他站在原地能否看见Yjq,帮助他解决这个问题。

    输入输出格式

    输入输出格式

    输入格式:

    第一行两个数xv,yv,表示Hja的坐标。

    第二行两个数xp,yp表示Yjq的坐标。

    第三行四个数xw1,yw1,xw2,yw2,分别表示墙的两个端点的坐标。

    第四行四个数xm1,ym1,?xm2,ym2,分别表示镜子的两个端点的坐标。

    输出格式:

    如果Hja站在原地能看到Yjq,则输出"YES",否则输出"NO"。

    输入输出样例

    输入样例#1:
    -1 3
    1 3
    0 2 0 4
    0 0 0 1
    输出样例#1:
    NO
    输入样例#2:
    0 0
    1 1
    0 1 1 0
    -100 -100 -101 -101
    输出样例#2:
    NO
    输入样例#3:
    0 0
    1 1
    0 1 1 0
    -1 1 1 3
    输出样例#3:
    YES
    输入样例#4:
    0 0
    10 0
    100 100 101 101
    1 0 3 0
    输出样例#4:
    YES

    说明

    对于 100%的数据, 所有坐标均为绝对值不超过 所有坐标均为绝对值不超过 104的整数。输入线段不会 的整数。输入线段不会 退化成点,且两条线段没有交。 退化成点,且两条线段没有交。 Hja和 Yjq的位置不同,且在任何一条线段 的位置不同,且在任何一条线段上

      1 /*
      2     叉积 
      3 两个人如果能看见
      4 1、两人之间无墙无镜子(直接看两人连线与墙和镜子有无交点) 
      5 2、两人之间有墙,但是能通过镜子看到(找两人视线在镜子所在直线的交点,判断交点是否在镜子上) 
      6 */
      7 
      8 #include<cstdio>
      9 #include<cstdlib>
     10 #include<cstring>
     11 #include<cmath>
     12 #include<algorithm>
     13 using namespace std;
     14 const double eps=1e-8;
     15 int sgn(double a)
     16 {
     17     if (fabs(a)<eps) return 0;
     18     else
     19     {
     20         if (a>0.0) return 1;
     21         else return -1;
     22     }
     23 }
     24 struct point
     25 {
     26     double x,y;
     27     point(){}
     28     point(double a,double b)
     29     {
     30         x=a;y=b;
     31     }
     32     void init()
     33     {
     34         scanf("%lf%lf",&x,&y);
     35     }
     36     point operator+(const point &a)const
     37     {
     38         point ans;
     39         ans.x=x+a.x;
     40         ans.y=y+a.y;
     41         return ans;
     42     }
     43     point operator-(const point &a)const
     44     {
     45         point ans;
     46         ans.x=x-a.x;
     47         ans.y=y-a.y;
     48         return ans;
     49     }
     50     point operator*(const double &a)const
     51     {
     52         point ans;
     53         ans.x=x*a;
     54         ans.y=y*a;
     55         return ans;
     56     }
     57     void print()
     58     {
     59         printf("%lf %lf
    ",x,y);
     60     }
     61 }v,p,w1,w2,m1,m2;
     62 double cross(point a,point b)
     63 {
     64     return a.x*b.y-a.y*b.x;
     65 }
     66 double dot(point a,point b)
     67 {
     68     return a.x*b.x+a.y*b.y;
     69 }
     70 bool cross(point p1,point p2,point p3,point p4)
     71 {
     72     if(sgn(cross(p2-p1,p3-p1))*sgn(cross(p2-p1,p4-p1))==1) return false;
     73     if(sgn(cross(p4-p3,p1-p3))*sgn(cross(p4-p3,p2-p3))==1) return false;
     74     if(sgn(max(p1.x,p2.x)-min(p3.x,p4.x))==-1) return false;
     75     if(sgn(max(p1.y,p2.y)-min(p3.y,p4.y))==-1) return false;
     76     if(sgn(max(p3.x,p4.x)-min(p1.x,p2.x))==-1) return false;
     77     if(sgn(max(p3.y,p4.y)-min(p1.y,p2.y))==-1) return false;
     78     return true;
     79 }
     80 point getcross(point p1,point p2,point p3,point p4)
     81 {
     82     double a=p2.y-p1.y;
     83     double b=p1.x-p2.x;
     84     double c=-p1.x*p2.y+p1.y*p2.x;
     85     double d=p4.y-p3.y;
     86     double e=p3.x-p4.x;
     87     double f=-p3.x*p4.y+p3.y*p4.x;
     88     double x=(b*f-c*e)/(a*e-b*d);
     89     double y=(a*f-c*d)/(b*d-a*e);
     90     return point(x,y);
     91 }
     92 point calcfoot(point p1,point p2,point p3)
     93 {
     94     double ratio=dot(p1-p2,p3-p2)/dot(p3-p2,p3-p2);
     95     return p2+(p3-p2)*ratio;
     96 }
     97 bool check()
     98 {
     99     if(!cross(v,p,w1,w2))    //没有墙阻挡 
    100     {
    101         if(!cross(v,p,m1,m2)) return true;    //也没有镜子阻挡 
    102         if(sgn(cross(m1-v,m2-v))==0&&sgn(cross(m1-p,m2-p)==0)) return true;    //与镜子平行      
    103     }
    104     if(sgn(cross(m2-m1,v-m1))*sgn(cross(m2-m1,p-m1))==1)    //计算镜子所在直线上的折射点 
    105     {
    106         point foot=calcfoot(p,m1,m2);
    107         foot=foot*2.0-p;
    108         if(cross(v,foot,m1,m2))        //折射点在镜子上 
    109         {
    110             foot=getcross(v,foot,m1,m2);
    111             if(!cross(v,foot,w1,w2)&&!cross(foot,p,w1,w2)) return true;    //判断两个人的目光是否会被墙打断 
    112         }
    113     }
    114     return false;
    115 }
    116 int main()
    117 {
    118     freopen("b.in","r",stdin);
    119     freopen("b.out","w",stdout);
    120     v.init();
    121     p.init();
    122     w1.init();
    123     w2.init();
    124     m1.init();
    125     m2.init();
    126     if (check()) printf("YES
    ");
    127     else printf("NO
    ");
    128     return 0;
    129 }
    View Code
  • 相关阅读:
    android一些细节问题
    Android Suspend/resume 过程分析.
    在NDK上建立自己的项目
    ListView加载特效
    Android Log Analysis转
    Android系统默认设置
    一步步分析Log
    Android Framework 分析
    编译安装MariaDB10.0.21
    mariadb多源复制 muiltil source replication
  • 原文地址:https://www.cnblogs.com/lovewhy/p/7652894.html
Copyright © 2011-2022 走看看