hrbust OJ 1471 水神的激光笔

来源:互联网 发布:mac视频编辑软件下载 编辑:程序博客网 时间:2024/04/28 01:40
Description


水神喜欢玩,这次水神买了一支激光笔,因为激光笔晃人很有趣,至少水神是这样想的。但是毕竟直接用激光笔晃人是在是太恶劣了,因此水神打算借用一个平面镜来达到目的,这样就不容易被人发现了。

注意:

1、我们认为激光可以传播无限远的距离  

2、我们认为平面镜只进行镜面反射

3、平面镜正反两面都可以反光,有且只有这两个面能反光

4、水神不会用激光笔垂直照射平面镜镜面,因为那样水神会晃到自己


Input

第一行一个整数T,代表测试数据组数(1<=T<=50)

对于每组数据:第一行和第二行输入两个浮点数 x1 y1和 x2 y2 表示平面镜两个端点的坐标(这里我们只研究二维平面内的问题,因此镜子可以看做线段),第三行输入两个浮点数 x3 y3 表示水神的激光笔的坐标(水神的激光笔可以在该坐标的位置上转动),第四行输入两个浮点数 x4 y4 表示水神目标位置的坐标。

Output

如果水神能够通过平面镜间接用激光笔找到目标,请输出激光在平面镜上的反射点(保留三位小数)并换行,否则输出"ShuiShen Failed" (不包括引号),并换行。

注意,每组输出后有一个空行!

Sample Input2
0.000 0.000
4.000 0.000
1.000 1.000
3.000 1.000
0.000 0.000
4.000 0.000
1.000 1.000
100.000 1.000Sample Output
Test #1:The Point is:(2.000,0.000)Test #2:ShuiShen Failed

 

 

#include<stdio.h>#include<iostream>#include<cmath>using namespace std;typedef struct{    double x, y;}point_x_y;typedef struct{    double a, b, c;}line;typedef struct{    point_x_y s, e;}Line_set;double min(double a, double b){   return  a > b ? b : a;}double max(double a, double b){   return  a > b ? a : b;}// 根据已知两点坐标,求过这两点的直线解析方程: a*x+b*y+c = 0 (a >= 0)line qiu_Line(point_x_y p1, point_x_y p2){    line tl;    int sign = 1;    tl.a=p2.y-p1.y;    if(tl.a<0)    {    sign = -1;    tl.a=sign*tl.a;    }    tl.b=sign*(p1.x-p2.x);    tl.c=sign*(p1.y*p2.x-p1.x*p2.y);    return tl;}//叉积double multi(point_x_y p0, point_x_y p1, point_x_y p2){    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}//判断线段是否相交bool cross(point_x_y s1, point_x_y e1, point_x_y s2, point_x_y e2){    if((min(s1.x, e1.x)<=max(s2.x, e2.x))&&min(s1.y, e1.y)<=max(s2.y, e2.y)       &&min(s2.x, e2.x)<=max(s1.x, e1.x)&&min(s2.y, e2.y)<=max(s1.y, e1.y)       &&multi(s1, e1, s2)*multi(s1, e1, e2)<=0&&       multi(s2, e2, s1)*multi(s2, e2, e1)<=0)       return true;       return false;}//求p关于直线l的对称点point_x_y symmetry(line l,point_x_y p){point_x_y tp;tp.x=((l.b*l.b-l.a*l.a)*p.x-2*l.a*l.b*p.y-2*l.a*l.c)/(l.a*l.a+l.b*l.b);tp.y=((l.a*l.a-l.b*l.b)*p.y-2*l.a*l.b*p.x-2*l.b*l.c)/(l.a*l.a+l.b*l.b);return tp;}//求l1,l2的交点pbool lineintersect(line l1,line l2,point_x_y &p){double d=l1.a*l2.b-l2.a*l1.b;if(abs(d)<1e-10)return false;p.x = (l2.c*l1.b-l1.c*l2.b)/d;p.y = (l2.a*l1.c-l1.a*l2.c)/d;return true;}bool online(line l,point_x_y p){    double y0=-1*(l.a/l.b)*p.x-(l.c/l.b);    return (abs(y0-p.y)<1e-10);}int main(){    int T, i;    point_x_y z1, z2, z3, z4;    scanf("%d",&T);   for(i=1;i<=T;i++)    {        scanf("%lf%lf%lf%lf%lf%lf%lf%lf", &z1.x,&z1.y,&z2.x,&z2.y,&z3.x,&z3.y,&z4.x,&z4.y);        line t1, t2;        t1=qiu_Line(z1, z2);        point_x_y tp;        tp=symmetry(t1, z3);        if(!cross(tp, z4, z1, z2)||online(t1, z3)) printf("Test #%d:\nShuiShen Failed\n\n",i);        else {            t2=qiu_Line(tp, z4);            point_x_y p;            lineintersect(t1, t2, p);            printf("Test #%d:\nThe Point is:(%.3lf,%.3lf)\n\n",i,p.x,p.y );        }    }  return 0;}


 

 

 

原创粉丝点击