Description |
水神喜欢玩,这次水神买了一支激光笔,因为激光笔晃人很有趣,至少水神是这样想的。但是毕竟直接用激光笔晃人是在是太恶劣了,因此水神打算借用一个平面镜来达到目的,这样就不容易被人发现了。 注意: 1、我们认为激光可以传播无限远的距离 2、我们认为平面镜只进行镜面反射 3、平面镜正反两面都可以反光,有且只有这两个面能反光 4、水神不会用激光笔垂直照射平面镜镜面,因为那样水神会晃到自己
|
Input |
第一行一个整数T,代表测试数据组数(1<=T<=50) 对于每组数据:第一行和第二行输入两个浮点数 x1 y1和 x2 y2 表示平面镜两个端点的坐标(这里我们只研究二维平面内的问题,因此镜子可以看做线段),第三行输入两个浮点数 x3 y3 表示水神的激光笔的坐标(水神的激光笔可以在该坐标的位置上转动),第四行输入两个浮点数 x4 y4 表示水神目标位置的坐标。 |
Output |
如果水神能够通过平面镜间接用激光笔找到目标,请输出激光在平面镜上的反射点(保留三位小数)并换行,否则输出"ShuiShen Failed" (不包括引号),并换行。 注意,每组输出后有一个空行! |
Sample Input |
2 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.000 |
Sample 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的交点p bool 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; }