poj1093 向量

首先说,上大学这么长时间数学是真的是忘的差不多了,求两个直线的交点竟然让我纠结了好长时间。。。

题的大意是给一个曲折的管子,当光线照入时求可以照的最长的距离!

思路:对于可以照的最长的管子,总是经过管子的上下转折点的,所以可以采用枚举上下转折点来求得光线可以最长到达的距离!

对于每个枚举出来的直线,对于每一个上下转折点,如果上转折点在下方的话就是有交点了,下转折点在直线的上方就也是有交点了,求出交点,找到最大的x就可以了!

分析了别人的代码,那个上面有很多简化的部分,有点看不懂额,所以我就用他的思路但是没有写简化的部分,菜鸟啊啊啊啊啊!

#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
typedef struct point
{
	double x,y;
}rr;
#define exp 0.000000001
point up[25],down[25];
int n;
double Max;
double judge(point p1,point p2,point p3)
{
	return (p3.y-p1.y)*(p2.x-p1.x)-(p2.y-p1.y)*(p3.x-p1.x);
}
void len(point p1,point p2,point p3,point p4)
{
	double k=(p1.y-p2.y)/(p1.x-p2.x);
	double b=p1.y-p1.x*k;
 
		double k1=(p3.y-p4.y)/(p3.x-p4.x);
		double b1=p3.y-k1*p3.x;
	double	x=(b-b1)/(k1-k);
	if(x>Max)
		Max=x;
}
int fun(point s,point t)
{
     int i,flag=0;
	 if(judge(s,t,up[0])<-exp || judge(s,t,down[0])>exp)
		 return 0;
	 for(i=1; i<=n-1; i++)
	 {
          if(judge(s,t,up[i])<-exp)
		  {
			  flag=1;
			  break;
		  }
		  if(judge(s,t,down[i])>exp)
		  {
			  flag=2;
			  break;
		  }
	 }
	 if(i==n)
		 return 1;
//	 if(i<j)//在j之前的有个点该光线都不可以通过,那么就直接舍弃了
//		 return 0;
	 point p1,p2;
	 if(flag==1)
	 {
		 p1=up[i-1];
		 p2=up[i];
	 }
	 if(flag==2)
	 {
		 p1=down[i-1];
		 p2=down[i];
	 }
	 len(s,t,p1,p2);
	 return 0;
}
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;
		}
		int sign=0;
		Max=-10000000;
		for(i=0; i<n; i++)
		{
			for(j=i+1; j<n; j++)
			{
				if(fun(up[i],down[j]))//对点进行枚举的
				{
					sign=1;
					break;
				}
				if(fun(down[i],up[j]))
				{
					sign=1;
					break;
				}
			}
		}
		if(sign==1)
			printf("Through all the pipe.\n");
		else
			printf("%0.2lf\n",Max);
	}
	return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

淡定的小Y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值