nyoj 142 管道问题(线段相交问题)
来源:互联网 发布:微博系统源码 编辑:程序博客网 时间:2024/06/05 12:03
描述
有一宽度为1的折线管道,如图所示,上面的各个定点为 (x0,y0),(x1,y1),(x2,y2) ……(xn,yn),下面各个定点为(x0,y0-1),(x1,y1-1),(x2,y2-1)……(xn,yn-1),假设管道都是不透明的,不反射的,光线从左边入口的(x0,y0),(x0,y0-1)之间射入,向四面八方直线传播,问光线最远能射到哪里(x坐标)或能穿透整个管道。
输入
第一行有一个整数2<=n<20(n为零结束),表示有n个管道,接下来的n行表示n个管道的上面坐标(x0,y0),(x1,y1),(x2,y2)……(xn,yn)。测试数据组数大于0小于10000,所有坐标的只不大于10000。
输出
如果光线不能穿过管道,输出最远的x坐标,结果保留两位小数。如果有光线可以透过管道,输出“Through all the pipe.”
样例输入
4
0 1
2 2
4 1
6 4
6
0 1
2 -0.6
5 -4.45
7 -5.57
12 -10.8
17 -16.55
0
样例输出
4.67
有一宽度为1的折线管道,如图所示,上面的各个定点为 (x0,y0),(x1,y1),(x2,y2) ……(xn,yn),下面各个定点为(x0,y0-1),(x1,y1-1),(x2,y2-1)……(xn,yn-1),假设管道都是不透明的,不反射的,光线从左边入口的(x0,y0),(x0,y0-1)之间射入,向四面八方直线传播,问光线最远能射到哪里(x坐标)或能穿透整个管道。
输入
第一行有一个整数2<=n<20(n为零结束),表示有n个管道,接下来的n行表示n个管道的上面坐标(x0,y0),(x1,y1),(x2,y2)……(xn,yn)。测试数据组数大于0小于10000,所有坐标的只不大于10000。
输出
如果光线不能穿过管道,输出最远的x坐标,结果保留两位小数。如果有光线可以透过管道,输出“Through all the pipe.”
样例输入
4
0 1
2 2
4 1
6 4
6
0 1
2 -0.6
5 -4.45
7 -5.57
12 -10.8
17 -16.55
0
样例输出
4.67
Through all the pipe
主要的思路就是穷举所有的折点的组合,取任意两个折点组成一条线,看看能不能跟所有的管道的上下折点构成的线段相交,如果所有都相交则说明光线能通过,否则求出所有光线中照的最远的那个(穷举的过程中设置一个记录变量) 这里就需要计算两个线段的交点(如果不能穿过管道,就要计算管道壁和光线的交点)。
#include<stdio.h>#include<iostream>#include<string.h>#include<math.h>#include<algorithm>#define E 1e-10using namespace std;struct zz{ double x; double y;} p[25][2];double judge(zz a,zz b,zz c)//判断左右方向{ return ((b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y));}double check(zz a1,zz a2,zz b1,zz b2)//判断是否相交{ return judge(a1,a2,b1)*(judge(a1,a2,b2));}double zhexian(zz a,zz b,zz c)//计算三角形面积公式{ double s=((b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y))/2.0; return fabs(s);}double point(zz a1,zz a2,zz b1,zz b2)//计算交点坐标{ double s1,s2; s1=zhexian(a1,a2,b1); s2=zhexian(a1,a2,b2); return (s1*b2.x+s2*b1.x)/(s1+s2);}int main(){ int n; while(scanf("%d",&n),n) { int i,j; for(i=0; i<n; i++) { scanf("%lf%lf",&p[i][0].x,&p[i][0].y); p[i][1].x=p[i][0].x; p[i][1].y=p[i][0].y-1; } double mx=-0x3f3f3f3f; bool flag=false; zz a,b; for(i=0; i<n&&flag==false; i++) { for(int tmp=0; tmp<2; tmp++) { a=p[i][tmp]; for(int x1=i+1; x1<n&&flag==false; x1++) { for(int x2=0; x2<2&&flag==false; x2++) { b=p[x1][x2]; if(check(a,b,p[0][0],p[0][1])<E)///相交说明光线是从管道口进入 { for(j=1; j<n; j++) { if(check(a,b,p[j][0],p[j][1])>E)//如果a,b两点所连直线在p[j][1]、p[j][0],这个折点处没有交点,那么光线在这附近会有交点。 { double x; if(judge(a,b,p[j][0])>0) x=point(a,b,p[j-1][1],p[j][1]); else x=point(a,b,p[j-1][0],p[j][0]); if(x>mx) mx=x; break; } } if(j==n) flag=true; } } } } } if(flag==true) printf("Through all the pipe.\n"); else printf("%.2lf\n",mx); } return 0;}
0 0
- nyoj 142 管道问题(线段相交问题)
- nyoj 83 迷宫寻宝(二)(线段相交问题)
- nyoj 1132 promise me a medal(线段相交问题)
- NYOJ 142 管道问题
- HDOJ1086 线段相交问题
- nyoj 管道问题 142 (数学计算几何)
- POJ 2653 线段相交问题
- NYOJ 14 会场安排问题(选择不相交区间)
- nyoj--1036--非洲小孩(区间相交问题)
- POJ2653(Pick-up sticks)(线段相交问题)
- POJ 3347 Kadj Squares(复杂的线段相交问题)
- POJ 2074 线段相交 视线问题
- zoj 1010 Area【线段相交问题】
- poj2653-Pick-up sticks(线段相交问题)
- hdu Pick-up sticks 线段相交问题
- 计算几何中的线段相交判断问题
- poj2074 线段相交的视线问题
- 线段相交之精粹和交点问题
- 高性能阻塞队列
- More Effective C++----(23)考虑变更程序库
- postgreSQL中函数json_populate_recordset的参数null::myrowtype如何使用
- nyoj18 The Triangle
- 介绍几款AI开源平台
- nyoj 142 管道问题(线段相交问题)
- java编程心得
- 命令模式:封装一系列动作执行的步骤
- Fuel7.0安装
- Ubuntu16.04 mysql基本命令
- HDOJ(HDU) 2304 Electrical Outlets(求和、、)
- java版本的神经网络——开源框架JOONE实践
- 趣谈Java变量的可见性问题
- 状态模式:把执行的动作封装在跟状态有关的类里,由状态来决定动作该如何执行