< 胡策day> 10.26 T2 人、镜子与墙
2017-10-26 18:13
176 查看
*PS:不得不说这个题好恶心啊,注意的细节超多!!!〒▽〒话说这套题是MC和老窦要的吗???
题目来源: 钟长者
Hja 和 Yjq 在玩捉迷藏。 Yjq 躲了起来, Hja 要找他。在他们玩游戏的房间里,只有一堵不透明的墙和一个双面的镜子。 Hja 和 Yjq 可以看作平面上坐标分别为(Xv, Yv)和(Xp, Yp)的点。墙是一条连接(Xw1, Yw1)和(Xw2, Yw2)的线段,镜子是一条连接(Xm1, Ym1)和(Xm2, Ym2)的线段。
如果视线和障碍物有公共点,那么我们认为视线会被阻挡,无法看见。如果视线和镜子有公共点,那么我们认为发生了反射。反射的过程遵循物理规律——入射角等于反射角,且反射光线与入射光线在镜子同侧。也就是说,想要看见对方, Hja 和 Yjq 必须在镜子的同一侧,包括镜子所在直线上(参见样例 1)。 如果视线与镜子重合,那么不会发生反射,并且镜子不被当作障碍物(参见样例 4)。
Hja 很想知道他站在原地能否看见 Yjq,帮助他解决这个问题。
第二行两个数Xp, Yp表示 Yjq 的坐标。
第三行四个数Xw1, Yw1,Xw2, Yw2,分别表示墙的两个端点的坐标。
第四行四个数Xm1, Ym1 ,Xm2, Ym2,分别表示镜子的两个端点的坐标。
1 3
0 2 0 4
0 0 0 1
1 1
0 1 1 0
-100 -100 -101 -101
1 1
0 1 1 0
-1 1 1 3
10 0
100 100 101 101
1 0 3 0
一道细节超多的数学题与物理题。。。
墙挡住视线–> NO
镜子挡住视线–>NO
两个人在镜子两边–>NO
两个人无法通过镜子看到对方–>NO
……
不多说了,具体实现看代码吧。
PS:如果有错误的话欢迎指出哦φ(>ω<*)
题目来源: 钟长者
【问题描述】
你是能看到第二题的 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 31 3
0 2 0 4
0 0 0 1
样例输出 1
NO样例输入 2
0 01 1
0 1 1 0
-100 -100 -101 -101
样例输出 2
NO样例输入 3
0 01 1
0 1 1 0
-1 1 1 3
样例输出 3
YES样例输入 4
0 010 0
100 100 101 101
1 0 3 0
样例输出 4
YES【数据规模与约定】
对于100%的数据, 所有坐标均为绝对值不超过104的整数。输入的线段不会退化成点,且两条线段没有交点。 Hja 和 Yjq 的位置不同,且不在任何一条线段上。一道细节超多的数学题与物理题。。。
墙挡住视线–> NO
镜子挡住视线–>NO
两个人在镜子两边–>NO
两个人无法通过镜子看到对方–>NO
……
不多说了,具体实现看代码吧。
又麻烦又长的代码
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; const int inf=1e5; struct maple{ double x,y; }H,Y,W1,W2,M1,M2; maple jiaodian(maple a,maple b,maple A,maple B) // 求两直线交点 { maple c; double a1=(a.y-b.y)/(a.x-b.x),a2=(A.y-B.y)/(A.x-B.x); if(a.x-b.x==0) a1=inf; // 特判竖直 if(A.x-B.x==0) a2=inf; double b1=a.y-a1*a.x,b2=A.y-a2*A.x; if(a1!=inf&&a2!=inf) c.x=(b2-b1)/(a1-a2); else if(a1==inf) c.x=a.x; //特判竖直 else if(a2==inf) c.x=A.x; if(a1!=0&&a2!=0) c.y=a1*c.x+b1; else if(a1==0) c.y=a.y; //特判水平 else if(a2==0) c.y=A.y; return c; } bool can(maple a,maple b,maple A,maple B,int d) //判段两条线段是否相交和其他 { double a1=(a.y-b.y)/(a.x-b.x),a2=(A.y-B.y)/(A.x-B.x); if(a.x-b.x==0) a1=inf; //特判竖直情况 斜率=inf if(A.x-B.x==0) a2=inf; double b1=a.y-a1*a.x,b2=A.y-a2*A.x; if(a1==a2) if(b1!=b2) return true; // 判断两条线是否平行 else { if(A.x!=M1.x||A.y!=M1.y||B.x!=M2.x||B.y!=M2.y) // 特判:镜子可以与视线重合 if(min(A.x,B.x)<=max(a.x,b.x)&&max(A.x,B.x)>=min(a.x,b.x)) return false; //判断两条线段是否有重合部分 return true; } maple c=jiaodian(a,b,A,B); double X=c.x,Y=c.y; if(X<min(a.x,b.x)||X>max(a.x,b.x)) return true; // 判断交点是否不在第一条线段上 if(Y>max(a.y,b.y)||Y<min(a.y,b.y)) return true; if(A.x==M1.x&&A.y==M1.y&&B.x==M2.x&&B.y==M2.y&&d) return false; // 两个人分别在镜子两端当且仅当两点与镜子有交点且交点在视线上 if(X<min(A.x,B.x)||X>max(A.x,B.x)) return true; // 判断交点是否不在第二条线段上 if(Y>max(A.y,B.y)||Y<min(A.y,B.y)) return true; return false; } bool check() { if(can(H,Y,M1,M2,0)) //视线与镜子没有交点 if(can(H,Y,W1,W2,0)) return true; //与墙没有交点 if(!can(H,Y,M1,M2,1)) return false; //判断两点在镜子两侧 ,1为特判这种情况 double am=(M1.y-M2.y)/(M1.x-M2.x); // 求镜子的斜率 double ah=(-1)/am; //求垂直与镜子的直线的斜率 if(M1.x-M2.x==0) am=inf,ah=0; // 标记镜子的竖直情况 double bm=(M1.y-am*M1.x),bh=(H.y-ah*H.x); maple c,d; if(am!=inf&&am!=0) c.x=(bh-bm)/(am-ah); // 求过其中一个人的镜子的垂线与镜子的交点 else if(am==inf) c.x=M1.x; // 特判镜子的竖直情况 else if(am==0) c.x=H.x; // 特判镜子的水平情况 if(am!=inf&&am!=0) c.y=am*c.x+bm; else if(am==inf) c.y=H.y; else if(am==0) c.y=M1.y; c.x=2*c.x-H.x; // 求这个人关于镜子的对称点 c.y=2*c.y-H.y; d=jiaodian(c,Y,M1,M2); // 求这个对称点与另一个人的连线与镜子的交点 -->反射点 if(d.x<min(M1.x,M2.x)||d.x>max(M1.x,M2.x)) return false; // 判断反射点是否在镜子上 if(d.y>max(M1.y,M2.y)||d.y<min(M1.y,M2.y)) return false; if(!can(H,d,W1,W2,0)) return false; // 判断反射光线是否被墙阻断 if(!can(Y,d,W1,W2,0)) return false; return true; } int main() { freopen("b.in","r",stdin); freopen("b.out","w",stdout); scanf("%lf%lf",&H.x,&H.y); scanf("%lf%lf",&Y.x,&Y.y); scanf("%lf%lf%lf%lf",&W1.x,&W1.y,&W2.x,&W2.y); scanf("%lf%lf%lf%lf",&M1.x,&M1.y,&M2.x,&M2.y); if(check()) printf("YES"); else printf("NO"); return 0; }
PS:如果有错误的话欢迎指出哦φ(>ω<*)
相关文章推荐
- <胡策day> 10.26 T1 最大子串权值
- Func<T1, T2, TResult> Delegate 系统Func委托类型
- 谈谈Dictionary<T1,T2>和List<T>的问题
- BeanUtils<T1, T2> beanToBean
- Func<T1, T2, TResult> 泛型委托
- 谈谈Dictionary<T1,T2>和List<T>的问题 [转]
- <胡策day> 10.30 T1 小学数学
- BeanUtils<T1, T2> beanToBean
- Action<T1, T2>委托
- 生成代码,从 <T> 到 <T1, T2, Tn> —— 自动生成多个类型的泛型
- 使用Func<T1, T2, TResult>
- C# Tuple<T1,T2....T>元组的使用
- C# Tuple<T1,T2....T>元组的使用
- <MZ&DC联考>D2 T2
- 对复杂字典Dictionary<T1,T2>排序问题
- 如何声明和使用 Func<T1, T2, TResult> 委托
- T2 Func<in T1,out T2>(T1 arg)
- boost::variant<T1, T2>类型变量的适配
- <胡策day> 10.3 听说这套题很简单
- HNOI2016 Day2 T2 网络<树链剖分>