CodeForces 32E Hide-and-Seek(线段交,点关于直线对称点)

Hide-and-Seek

Description

Victor and Peter are playing hide-and-seek. Peter has hidden, and Victor is to find him. In the room where they are playing, there is only one non-transparent wall and one double-sided mirror. Victor and Peter are points with coordinates (xv, yv) and (xp, yp) respectively. The wall is a segment joining points with coordinates (xw, 1, yw, 1) and (xw, 2, yw, 2), the mirror — a segment joining points (xm, 1, ym, 1) and (xm, 2, ym, 2).

If an obstacle has a common point with a line of vision, it’s considered, that the boys can’t see each other with this line of vision. If the mirror has a common point with the line of vision, it’s considered, that the boys can see each other in the mirror, i.e. reflection takes place. The reflection process is governed by laws of physics — the angle of incidence is equal to the angle of reflection. The incident ray is in the same half-plane as the reflected ray, relative to the mirror. I.e. to see each other Victor and Peter should be to the same side of the line, containing the mirror (see example 1). If the line of vision is parallel to the mirror, reflection doesn’t take place, and the mirror isn’t regarded as an obstacle (see example 4).

Victor got interested if he can see Peter, while standing at the same spot. Help him solve this problem.

Input

The first line contains two numbers xv and yv — coordinates of Victor.

The second line contains two numbers xp and yp — coordinates of Peter.

The third line contains 4 numbers xw, 1, yw, 1, xw, 2, yw, 2 — coordinates of the wall.

The forth line contains 4 numbers xm, 1, ym, 1, xm, 2, ym, 2 — coordinates of the mirror.

All the coordinates are integer numbers, and don’t exceed 104 in absolute value. It’s guaranteed, that the segments don’t have common points, Victor and Peter are not on any of the segments, coordinates of Victor and Peter aren’t the same, the segments don’t degenerate into points.

Output

Output YES, if Victor can see Peter without leaving the initial spot. Otherwise output NO.

Sample Input
Input

-1 3
1 3
0 2 0 4
0 0 0 1

Output

NO

Input

0 0
1 1
0 1 1 0
-100 -100 -101 -101

Output

NO

Input

0 0
1 1
0 1 1 0
-1 1 1 3

Output

YES

Input

0 0
10 0
100 100 101 101
1 0 3 0

Output

YES

题意:给出二维坐标系中两人坐标,双面镜线段和非透明的墙线段,镜子的反射遵循物理规律,问两人是否能相互看到

线段交判断人与镜子和墙的关系,取对称时需要注意两个对称情况是否都没有被墙挡住

代码中符点关于直线对称点代码模板

#include<cstring>
#include<string>
#include<iostream>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<map>
#include<cstdlib>
#include<cmath>
#include<vector>
//#pragma comment(linker, "/STACK:1024000000,1024000000");

using namespace std;

#define INF 0x3f3f3f3f

struct Point
{
    double x,y;
    int kind;
    int id;
    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.y - y*b.x;
    }
//点积
    double operator *(const Point &b)const
    {
        return x*b.x + y*b.y;
    }
//绕原点旋转角度B(弧度值),后x,y的变化
    void transXY(double B)
    {
        double tx = x,ty = y;
        x = tx*cos(B) - ty*sin(B);
        y = tx*sin(B) + ty*cos(B);
    }
} V,P,W[2],M[2];

const double eps = 1e-8;
const double PI = acos(-1.0);
int sgn(double x)
{
    if(fabs(x) < eps)return 0;
    if(x < 0)return -1;
    else return 1;
}

struct Line
{
    Point s,e;
    Line() {}
    Line(Point _s,Point _e)
    {
        s = _s;
        e = _e;
    }
//两直线相交求交点
//第一个值为0表示直线重合,为1表示平行,为0表示相交,为2是相交
//只有第一个值为2时,交点才有意义
    pair<int,Point> operator &(const Line &b)const
    {
        Point res = s;
        if(sgn((s-e)^(b.s-b.e)) == 0)
        {
            if(sgn((s-b.e)^(b.s-b.e)) == 0)
                return make_pair(0,res);//重合
            else return make_pair(1,res);//平行
        }
        double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
        res.x += (e.x-s.x)*t;
        res.y += (e.y-s.y)*t;
        return make_pair(2,res);
    }
};

bool inter(Line l1,Line l2)
{
    return
        max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) &&
        max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) &&
        max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) &&
        max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) &&
        sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e)) <= 0 &&
        sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e)) <= 0;
}

void Sp(Point &A,Line X)
{
    double a=X.e.y-X.s.y;
    double b=X.s.x-X.e.x;
    double c=X.s.y*(X.e.x-X.s.x)-X.s.x*(X.e.y-X.s.y);
    double x = ((b*b - a*a) * A.x - 2 * a * b * A.y - 2 * a * c) / (a*a + b*b);
    double y = ((a*a - b*b) * A.y - 2 * a * b * A.x - 2 * b * c) / (a*a + b*b);
    A.x=x;
    A.y=y;
}

int main()
{
    scanf("%lf%lf%lf%lf",&V.x,&V.y,&P.x,&P.y);
    scanf("%lf%lf%lf%lf",&W[0].x,&W[0].y,&W[1].x,&W[1].y);
    scanf("%lf%lf%lf%lf",&M[0].x,&M[0].y,&M[1].x,&M[1].y);
    Line VP(V,P),WALL(W[0],W[1]),MIRROR(M[0],M[1]);
    if(!inter(VP,WALL)&&((M[0]-V)^(P-V))==0&&((M[1]-V)^(P-V))==0)
    {
        printf("YES\n");
    }
    else if(inter(VP,MIRROR))
    {
        printf("NO\n");
    }
    else if(!inter(VP,WALL))
    {
        printf("YES\n");
    }
    else
    {
        Point temp=V;
        Sp(temp,MIRROR);
        Line VP1(temp,P);
        temp=P;
        Sp(temp,MIRROR);
        Line VP2(temp,V);
        if(inter(VP1,MIRROR)&&!inter(VP1,WALL)&&!inter(VP2,WALL))
        {
            printf("YES\n");
        }
        else
        {
            printf("NO\n");
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值