【POJ】1039 Pipe -相交

传送门:poj1039


题解

射线必然过一个上转折点和一个下转折点,暴力枚举判断即可。

震惊: W A WA WA 7次竟是因为输出答案没有换行!


代码

#include<cstdio>
#include<cmath>
#include<algorithm>
typedef double db;
using namespace std;
const db eps=1e-5;
const int N=45;

int n;db ans;

struct P{
   db x,y;
   P(db x_=0.0,db y_=0.0):x(x_),y(y_){};
   inline P operator +(const P&ky){return P(x+ky.x,y+ky.y);}
   inline P operator -(const P&ky){return P(x-ky.x,y-ky.y);}
   inline db operator ^(const P&ky){return x*ky.y-y*ky.x;}
   inline P operator *(const db&ky){return P(x*ky,y*ky);}
   inline P operator /(const db&ky){return P(x/ky,y/ky);}
   inline db sq(){return sqrt(x*x+y*y);}
   bool operator <(const P&ky)const{
   	 db a=atan2(y,x),b=atan2(ky.y,ky.x);
   	 return a!=b?a<b:x<ky.x;
   } 
}p[N];

inline db dist(P a,P b){return (a-b).sq();}

struct Line{
	P st,ed,dir;
	Line(){};
	Line(P st_,P ed_){st=st_;ed=ed_;dir=ed-st;}
}nw;

inline int dcmp(db x){if(fabs(x)<eps) return 0;return x>0?1:-1;}
inline bool onlf(P a,P b,P c){return (dcmp((c-b)^(b-a))>-1);}

inline bool xj(P a,P b)
{return dcmp((nw.dir^(a-nw.st))*(nw.dir^(b-nw.st)))<1;}

inline db jd(P a,P b)
{
	db sa=fabs(nw.dir^(a-nw.st)),sb=fabs(nw.dir^(b-nw.st));
	return a.x+(b.x-a.x)*sa/(sa+sb);
}

inline void update(int pos,P st,P ed)
{
	if(ans==p[n].x) return;
	int i;nw=Line(st,ed);
	for(i=1;i<pos;++i) if(!xj(p[i],p[i+n])) return;
	for(i=pos;i<=n;++i)
	 if(!xj(p[i],p[i+n])){
	 	ans=max(ans,dcmp(nw.dir^(p[i]-st))>0?jd(p[i+n-1],p[i+n]):jd(p[i-1],p[i]));
		break;
	 }else ans=max(ans,p[i].x);
}

int main(){
	int i,j;
	for(;scanf("%d",&n)!=EOF;){
		if(!n) break;
		for(i=1;i<=n;++i) {
			scanf("%lf%lf",&p[i].x,&p[i].y);
			p[i+n]=P(p[i].x,p[i].y-1);
		}ans=p[1].x;
		for(i=1;i<=n;++i)
		 for(j=i+1;j<=n;++j)
		  update(j,p[i],p[j+n]),update(j,p[i+n],p[j]);
		if(!dcmp(ans-p[n].x)) puts("Through all the pipe.");
		else printf("%.2f\n",ans);
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值