poj1755Triathlon【半平面交】

本文探讨了如何通过调整铁人三项比赛各阶段的距离来确保指定选手获胜的问题。利用速度参数,采用半平面交算法确定可能的比赛长度配置。


Language:
Triathlon
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 6222 Accepted: 1572

Description

Triathlon is an athletic contest consisting of three consecutive sections that should be completed as fast as possible as a whole. The first section is swimming, the second section is riding bicycle and the third one is running. 

The speed of each contestant in all three sections is known. The judge can choose the length of each section arbitrarily provided that no section has zero length. As a result sometimes she could choose their lengths in such a way that some particular contestant would win the competition. 

Input

The first line of the input file contains integer number N (1 <= N <= 100), denoting the number of contestants. Then N lines follow, each line contains three integers Vi, Ui and Wi (1 <= Vi, Ui, Wi <= 10000), separated by spaces, denoting the speed of ith contestant in each section.

Output

For every contestant write to the output file one line, that contains word "Yes" if the judge could choose the lengths of the sections in such a way that this particular contestant would win (i.e. she is the only one who would come first), or word "No" if this is impossible.

Sample Input

9
10 2 6
10 7 3
5 6 7
3 2 7
6 2 6
3 5 7
8 4 6
10 4 2
1 8 7

Sample Output

Yes
Yes
Yes
No
No
No
Yes
No
Yes

题意:铁人三项比赛给出每个运动员在每项比赛中的速度求是否存在一种路程分配使得该运动员成为冠军

要使运动员成为冠军则有三段路程X,Y,Z X/V1+Y/V2+Z/V3>X/V4+Y/V5+Z/V6 移项并同时除Z即可消去一项用半平面交即可解决

AC代码

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define eps 1e-16
#define   inf 1<<30
#define zero(a) fabs(a)<eps 
using namespace std;
struct point{
	double x,y;
}p[2010],q[2010];
struct line{
	double a,b,c;
}K[105];
int endcnt,tempcnt;
point getinter(point p1,point p2,double a,double b,double c){
	double u=fabs(a*p1.x+b*p1.y+c);
	double v=fabs(a*p2.x+b*p2.y+c);
	point temp;
	temp.x=(p1.x*v+p2.x*u)/(u+v);
	temp.y=(p1.y*v+p2.y*u)/(u+v);
	return temp;
} 
double calculatearea(){
	double area=0;
	for(int i=1;i<=endcnt;++i){
		area+=p[i].x*p[i+1].y-p[i].y*p[i+1].x;
	}
	return area;
}
void cut(double a,double b,double c){
	tempcnt=0;
	for(int i=1;i<=endcnt;++i){
		if(a*p[i].x+b*p[i].y+c>=0)q[++tempcnt]=p[i];
		else{
			if(a*p[i-1].x+b*p[i-1].y+c>0){
				q[++tempcnt]=getinter(p[i],p[i-1],a,b,c);
			}
			if(a*p[i+1].x+b*p[i+1].y+c>0){
				q[++tempcnt]=getinter(p[i],p[i+1],a,b,c);
			}
		}
	}
	for(int i=1;i<=tempcnt;++i){
		p[i]=q[i];
	}
	p[tempcnt+1]=p[1];p[0]=p[tempcnt];
	endcnt=tempcnt;
}
bool slove(int n,int pos){
	p[1].x=0;p[1].y=0;
	p[2].x=0;p[2].y=inf;
	p[3].x=inf;p[3].y=inf;
	p[4].x=inf;p[4].y=0;
	p[0]=p[4];p[5]=p[1];
	endcnt=4;
	for(int i=0;i<n;++i){
		if(i==pos)continue;
		double a,b,c;
		a=(K[pos].a-K[i].a)/(K[pos].a*K[i].a);
		b=(K[pos].b-K[i].b)/(K[pos].b*K[i].b);
		c=(K[pos].c-K[i].c)/(K[pos].c*K[i].c);
		if(a==0&&b==0&&c<eps)return false;
		cut(a,b,c);
	}//return !zero(calculatearea());
	if(calculatearea()<0)
		return true;
	return false;
}
int main()
{
	int n,i,j,k;
	while(scanf("%d",&n)!=EOF){
		for(i=0;i<n;++i){
			scanf("%lf%lf%lf",&K[i].a,&K[i].b,&K[i].c);
		}
		for(i=0;i<n;++i){
			if(slove(n,i))
				printf("Yes\n");
			else
				printf("No\n");
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值