zoukankan      html  css  js  c++  java
  • 一道基本的计算几何题

    题目大意:

    两个人在坐标系内,可以通过镜子的反射来看到对方,但是会有一堵墙阻挡,问两个人能否看到对方

    若两个人与镜子共线,则镜子不会阻挡两个人的视线。而给出的镜子和墙不会相交

    思路:

    看到只有两种情况

    第一种 两个人直接看到

    第二种 两个人直接通过镜子看到

    对于这种情况,我们直接判断他们是否在镜子一侧,他们与对方对称点连成的线段与镜子相交且不与墙相交,这五个东西即可

    但是这种情况看上去不符合第二种的判断但其实是可以看到的,但是如果这种情况就直接看到了,哪还需要什么镜子。。。

    TAT跪了两个点不知道为什么 本蒟蒻很无奈

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<queue>
     8 #include<vector>
     9 #include<stack>
    10 #include<set>
    11 #include<map>
    12 #define inf 2147483611
    13 #define ll long long
    14 #define MAXN 101010
    15 using namespace std;
    16 inline int read()
    17 {
    18     int x=0,f=1;
    19     char ch;ch=getchar();
    20     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    21     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    22     return x*f;
    23 }
    24 struct node
    25 {
    26     double x,y;
    27 }a,b,vb,va,m1,m2,w1,w2;
    28 double mult(node a,node b,node c)//叉积 
    29 {  
    30     return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);  
    31 }
    32 bool intct(node a,node b,node c,node d)//判两线段是否相交 
    33 {  
    34     if(max(a.x,b.x)<min(c.x,d.x)) return false;
    35     if(max(a.y,b.y)<min(c.y,d.y)) return false;
    36     if(max(c.x,d.x)<min(a.x,b.x)) return false;
    37     if(max(c.y,d.y)<min(a.y,b.y)) return false;
    38     if(mult(c,b,a)*mult(b,d,a)<0) return false;
    39     if(mult(a,d,c)*mult(d,b,c)<0) return false;
    40     return true;  
    41 }
    42 int main()
    43 {
    44     scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y);
    45     scanf("%lf%lf%lf%lf",&w1.x,&w1.y,&w2.x,&w2.y);
    46     scanf("%lf%lf%lf%lf",&m1.x,&m1.y,&m2.x,&m2.y);
    47     bool inw=intct(a,b,w1,w2),inm=intct(a,b,m1,m2);//是否与墙交,是否与镜子交 
    48     if(!inw&&!inm) {printf("YES");return 0;}//是否能直接看到 
    49     double A=m2.y-m1.y,B=m1.x-m2.x,C=m2.x*m1.y-m1.x*m2.y;//求镜子所在直线 
    50     if(A*a.x+B*a.y+C==0&&A*b.x+B*b.y+C==0&&!inw) {printf("YES");return 0;}//判断镜子与两个人是否共线 
    51     vb.x=b.x-2*A*(A*b.x+B*b.y+C)/(A*A+B*B);//求两个人的翻折点坐标 
    52     vb.y=b.y-2*B*(A*b.x+B*b.y+C)/(A*A+B*B);
    53     va.x=a.x-2*A*(A*a.x+B*a.y+C)/(A*A+B*B);
    54     va.y=a.y-2*B*(A*a.x+B*a.y+C)/(A*A+B*B);
    55     node minf1,minf2;minf1.x=-10101.0,minf2.x=10101.0;
    56     minf1.y=(C-A*minf1.x)/B,minf2.y=(C-A*minf2.x)/B;
    57     if(!intct(a,b,minf1,minf2)&&intct(a,vb,m1,m2)&&intct(b,va,m1,m2)&&!intct(a,vb,w1,w2)&&!intct(va,b,w1,w2)) {printf("YES");return 0;}
    58     // 是否在镜子同侧             点与另一个人的翻折点是否会穿过镜子    两个人的光路是否会穿过墙 
    59     printf("NO");
    60 }
    View Code
  • 相关阅读:
    解决Linux ssh登录马上退出问题
    FineReport实线java报表填报录入的效果图
    CCEditBox/CCEditBoxImplMac
    Android图片异步载入框架Android-Universal-Image-Loader
    HYAppFrame(WinForm框架源代码)安装部署指南
    ASP.NET Web Api 2 接口API文档美化之Swagger
    Android OTA在线升级一(架构分析)【转】
    Android进程间通信(IPC)机制Binder简要介绍和学习计划【转】
    Linux内核源码中的likely和unlikely释疑【转】
    Android蓝牙串口通讯【转】
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/7623853.html
Copyright © 2011-2022 走看看