版权声明:转载注明下出处就行了。 https://blog.csdn.net/LJD201724114126/article/details/83833656
题目链接:传送门
题意:有一条宽度为1(指的是上下管壁纵坐标之差,不是管道真实的宽度)的折线形管道,管道壁不透光不反光,求从管道一头射入一束光线,光线在管道内沿直线传播最远能传播多远(横坐标能到达的最大值)。
输入:每个测试用例一个数据块,第一个整数为折点数(2到20之间),接下来每行一个折点坐标(即上图中的一个点[x,y],x互不相等,按增序排列),表示管道的上边界折点,对应的下边界折点为[x,y-1].折点数位0时表示输入结束。
输出:每次用例输出一行,若光线能穿透整个管道,输出Through all the pipe.否则输出能到达的x值,保留两位小数。
题解:直接枚举
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
struct point
{
double x,y;
point(){}
point(double _x,double _y){
x=_x;y=_y;
}
};
point operator + (point a,point b) {return point(a.x+b.x,a.y+b.y);}
point operator - (point a,point b) {return point(a.x-b.x,a.y-b.y);}
point operator * (point a,double p) { return point(a.x*p,a.y*p);}
point operator / (point a,double p){ return point(a.x/p,a.y/p);}
bool operator < (const point &a,const point &b){
return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
const double esp=1e-8;
int dcmp(double x){
if(fabs(x)<esp) return 0;
else return x<0?-1:1;
}
bool operator ==(const point &a,const point &b){
return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}
double Cross(point A,point B) { return A.x*B.y-A.y*B.x;}
point Getlinenode(point P,point v,point Q,point w){ ///两参数方程求交点,(点,向量,点,向量)
point u=P-Q;
double t=Cross(w,u)/Cross(v,w);
return P+v*t;
}
bool isCross(point s1,point e1,point s2,point e2)///判断直线与线段是否相交
{
///首先判断向量s2e2 跨立 向量s1e1
double c1=Cross(s2-s1,e1-s1),c2=Cross(e1-s1,e2-s1);
///==0表示,相交于端点也认定为相交
if(dcmp(c1*c2)>=0) return true;
return false;
}
point p1[30],p2[30];
int main()
{
int n;
while(scanf("%d",&n)&&n)
{
double a,b;
for(int i=0;i<n;i++){
scanf("%lf%lf",&a,&b);
p1[i]=point(a,b);
p2[i]=point(a,b-1);
}
bool flag=true;
double ans=p1[0].x;
for(int i=0;i<n&&flag;i++)
{
for(int j=0;j<n&&flag;j++)
{
if(i==j) continue;
int k;
for( k=0;k<n;k++){
if(!isCross(p1[i],p2[j],p1[k],p2[k])){ ///判断直线ij与线段k是否相交
//
break;
}
}
if(k==n) {
flag=false;break;
}
else if(k>max(i,j)){
point item=Getlinenode(p1[i],p1[i]-p2[j],p1[k],p1[k]-p1[k-1]);
if(item.x>ans) ans=item.x;
item=Getlinenode(p1[i],p1[i]-p2[j],p2[k],p2[k]-p2[k-1]);
if(item.x>ans) ans=item.x;
// printf("ans=%.2f,k=%d\n",ans,k);
}
}
}
if(flag){
printf("%.2f\n",ans);
}
else printf("Through all the pipe.\n");
}
return 0;
}