poj 1755 Triathlon (半平面交求解不等式组)

原创 2017年01月04日 07:59:10

Triathlon
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 6881   Accepted: 1780

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

Source

[Submit]   [Go Back]   [Status]   [Discuss]


题目大意:有三项运动,给出每个人进行每项运动的速度,你可以自己确定三个项目的路程(不能为0),问是否存在方案使第i个人获胜,不能存在并列

题解:半平面交求解不等式组

假设要求第i个人是否可以获胜

那么我们可以得到一个不等式组(aj-ai)*x+(bj-bi)*y+(cj-ci)*z>0   (j!=i)

因为每项的路程不能为0,所以我们可以同时除以z,(aj-ai)*(x/z)+(bj-bi)*(y/z)+(cj-ci)>0

换元得 (aj-ai)*x+(bj-bi)*y+(cj-ci)>0

那么问题就转换成了求不等式组的可行域。

因为我们要统一取直线的右边或者左边(我取的左边),所以我们要针对不同的情况去不同的向量方向(在直线上取两个点即可)。 

直线的斜率单减,a>0 ,取的两点的横坐标单增

直线的斜率单减,a<0 ,取的两点的横坐标单减

直线的斜率单增,a>0 ,取的两点的横坐标单减

直线的斜率单增,a<0 ,取的两点的横坐标单增

总结一下,就是横坐标单增单减由b的正负决定,b<0单减,b>0单增

还有需要注意的是大框的边界,因为x>0,y>0,所以(inf,inf),(eps,inf),(eps,eps),(inf,eps)

再者因为是大于号,所以在直线上的点是取不到的,所以最后最好判断一下半平面交所形成的平面的面积是否为0.

这题的精度限制非常的恶心,要取到1e-16

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define N 103
#define eps 1e-16
#define inf 1000000000
using namespace std;
struct vector {
	double x,y;
	vector (double X=0,double Y=0){
		x=X,y=Y;
	}
}a1[N],p[N],tmp[N];
typedef vector point;
vector operator -(vector a,vector b){
	return vector (a.x-b.x,a.y-b.y);
}
vector operator +(vector a,vector b){
	return vector (a.x+b.x,a.y+b.y);
}
vector operator *(vector a,double t)
{
	return vector (a.x*t,a.y*t);
}
vector operator !=(vector a,vector b){
	return a.x!=b.x||a.y!=b.y;
}
struct data{
	point a,b;
}line[N];
double a[N],b[N],c[N];
int n,m;
void init()
{
	m=0;
	p[m++]=point(inf,inf);
	p[m++]=point(eps,inf);
	p[m++]=point(eps,eps);
	p[m++]=point(inf,eps);
}
int dcmp(double x)
{
	if (fabs(x)<eps) return 0;
	return x<0?-1:1;
}
double cross(vector a,vector b)
{
	return a.x*b.y-a.y*b.x;
}
point glt(point a,point a0,point b,point b0)
{
    double a1,b1,c1,a2,b2,c2;  
    a1 = a.y - a0.y;  
    b1 = a0.x - a.x;  
    c1 = cross(a,a0);  
    a2 = b.y - b0.y;  
    b2 = b0.x - b.x;  
    c2 = cross(b,b0);  
    double d = a1 * b2 - a2 * b1;  
    return point((b1 * c2 - b2 * c1) / d,(c1 * a2 - c2 * a1) / d);   
}
void cut(point a,point b)
{
	int cnt=0;
	memset(tmp,0,sizeof(tmp));
	for (int i=0;i<m;i++){
		double c=cross(b-a,p[i]-a);
		double d=cross(b-a,p[(i+1)%m]-a);
		if (dcmp(c)>=0) 
		  tmp[cnt++]=p[i];
		if (dcmp(c)*dcmp(d)<0) 
		 tmp[cnt++]=glt(a,b,p[i],p[(i+1)%m]);
	}
	m=0;
	for (int i=0;i<cnt;i++) 
	 if (m==0 || (tmp[i].x!=p[m-1].x||tmp[i].y!=p[m-1].y)) 
	   p[m++]=tmp[i];
}
int main()
{
	freopen("a.in","r",stdin);
	freopen("my.out","w",stdout);
	scanf("%d",&n);
	for (int i=1;i<=n;i++) scanf("%lf%lf%lf",&a[i],&b[i],&c[i]);
	for (int i=1;i<=n;i++){
		int k=0;
		bool mark=true;
		for (int j=1;j<=n;j++){
			if (i==j) continue;
			double nowa=1.0/a[j]-1.0/a[i];
			double nowb=1.0/b[j]-1.0/b[i];
			double nowc=1.0/c[j]-1.0/c[i];
			if (dcmp(nowa)==0&&dcmp(nowb)==0) {
				if (dcmp(nowc)>0) continue;
				else {
					mark=false;
					break;
				}
			}
			k++;
			if (dcmp(nowb)==0) {
				double t=-nowc/nowa;
				line[k].a.x=t; line[k].b.x=t;
				line[k].a.y=1; line[k].b.y=2;
				if (dcmp(nowa)>0) swap(line[k].a,line[k].b);
				continue;
			}
			line[k].a.x=1;
			line[k].a.y=-(nowa+nowc)/nowb;
			line[k].b.x=2;
			line[k].b.y=-(nowa*2.0+nowc)/nowb;
		    if (dcmp(nowb)<0) swap(line[k].a,line[k].b);
		}
		if (!mark){
			printf("No\n");
			continue;
		}
		init();
		for (int  j=1;j<=k;j++)
		 cut(line[j].a,line[j].b);
		double area=0; p[m]=p[0];
		for (int j=1;j<m;j++) area+=cross(p[j]-p[0],p[j+1]-p[0]);
		area=fabs(area);
		if (m>2&&dcmp(area)>0) printf("Yes\n");
		else printf("No\n");
	}
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

poj1755Triathlon【半平面交】

Language: Default Triathlon Time Limit: 1000MS   Memory Limit: 10000K Total Subm...
  • R1986799047
  • R1986799047
  • 2015年09月20日 01:22
  • 455

半平面交初级

半平面:顾名思义,半平面就是平面的一半,那么半平面应该如何表示呢?我们知道一条直线可以将平面分成两半,如果直线的方程为ax+by+c=0ax+by+c = 0,那么半平面就可以表示为ax+by+c0a...
  • huayunhualuo
  • huayunhualuo
  • 2016年04月15日 20:15
  • 794

poj 1755 Triathlon(半平面交解不等式)

n个人参加铁人三项的比赛,给出他们每一项的速度u,v,w,裁判可以决定每一项的距离,问是否存在一种安排,使得这个人能够赢。 对于每个人,如果存在安排的方法就输出Yes,没有就输出No。 这里可以假...
  • crazy852456
  • crazy852456
  • 2013年09月03日 19:21
  • 503

poj 1755 (半平面交解不等式)

转自http://blog.csdn.net/non_cease/article/details/7820361 题目链接:http://poj.org/problem?id=1755 ...
  • qq_34374664
  • qq_34374664
  • 2017年04月15日 20:23
  • 190

半平面交总结and模板

这两天刷了POJ上几道半平面交,对半平面交有了初步的体会,感觉半平面交还是个挺实用的知识点。 半平面交主要是看的ZZY的国家队论文,他提出的是一种O(n×log(n))的排序增量法。 附论文地址: 算...
  • xuechelingxiao
  • xuechelingxiao
  • 2014年11月06日 16:44
  • 2568

计算几何学习之半平面交

首先解决问题:什么是半平面? 顾名思义,半平面就是指平面的一半,我们知道,一条直线可以将平面分为两个部分,那么这两个部分就叫做两个半平面。 然后,半平面怎么表示呢? 二维坐标系下,直线可以表示为...
  • kep159
  • kep159
  • 2014年04月22日 15:51
  • 984

poj1279Art Gallery【半平面交求内核面积】

Language: Default Art Gallery Time Limit: 1000MS   Memory Limit: 10000K Total Su...
  • R1986799047
  • R1986799047
  • 2015年09月14日 23:45
  • 618

POJ 1755 半平面交

Triathlon Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5244   Acce...
  • u012358934
  • u012358934
  • 2014年05月11日 16:22
  • 633

POJ 2451 nlog(n)半平面交裸题。

Uyuw's Concert Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 6587   ...
  • u012358934
  • u012358934
  • 2014年05月04日 18:44
  • 971

poj 1755 Triathlon(半平面交解可行域)

Triathlon Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4990   Accepted: 1251 ...
  • u010527492
  • u010527492
  • 2013年12月31日 15:40
  • 484
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:poj 1755 Triathlon (半平面交求解不等式组)
举报原因:
原因补充:

(最多只允许输入30个字)