标签:des style http color os io strong for ar
| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 9110 | Accepted: 2755 |
Description

Input
Output
Sample Input
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
Sample Output
4.67 Through all the pipe.
思路:计算几何。从结果反过来可以证:如果一根光线没有擦到2个顶点,那肯定不是最优的解(可以移动或旋转取到一个更优解)。枚举上下两个顶点成光线所在直线,然后判断光线是否能合法,合法的话求出它射到的最远距离
#include"stdio.h"
#include"string.h"
#include"math.h"
#include"iostream"
#include"algorithm"
using namespace std;
#define LL __int64
#define N 30
const double eps=1e-8;
#define max(a,b) ((a)>(b)?(a):(b))
struct point //存储点坐标
{
double x,y;
}up[N],down[N];
double ans;
int n;
double Cross(point a,point b,point c) //叉积判断点与直线位置关系
{ //若点在直线逆时针方向,返回正值
return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
bool fun(point a,point b,int m)
{
int i,sign;
double x1,x2,x3,x4,y1,y2,y3,y4,aa,bb,cc,dd,x;
for(i=0;i<n;i++)
{
if(Cross(a,b,up[i])<-eps) //管道顶点在直线下方
{
sign=1;break;
}
if(Cross(a,b,down[i])>eps) //管道底在直线上方
{
sign=2;break;
}
}
if(i==n)
return true;
if(i<m)
return false;
if(sign==1) //求两直线交点横坐标
{
x1=up[i-1].x;
y1=up[i-1].y;
x2=up[i].x;
y2=up[i].y;
}
else
{
x1=down[i-1].x;
y1=down[i-1].y;
x2=down[i].x;
y2=down[i].y;
}
x3=a.x;y3=a.y;x4=b.x;y4=b.y;
aa=x2-x1;bb=y2-y1;cc=x4-x3;dd=y4-y3;
x=((y3-y1)*(aa*cc)+bb*cc*x1-aa*dd*x3)/(bb*cc-aa*dd);
ans=max(ans,x);
return false;
}
int main()
{
int i,j;
while(scanf("%d",&n),n)
{
for(i=0;i<n;i++)
{
scanf("%lf%lf",&up[i].x,&up[i].y);
down[i].x=up[i].x;
down[i].y=up[i].y-1;
}
ans=-1000000;
bool flag=false;
for(i=0;i<n&&!flag;i++)
{
for(j=i+1;j<n;j++)
{
flag=fun(up[i],down[j],j);
if(flag)
break;
flag=fun(down[i],up[j],j);
if(flag)
break;
}
}
if(flag)
printf("Through all the pipe.\n");
else
printf("%.2f\n",ans);
}
return 0;
}
标签:des style http color os io strong for ar
原文地址:http://blog.csdn.net/u011721440/article/details/38797517