您的位置:首页 > 其它

bzoj 3800: Saber VS Lancer (半平面交求解不等式组)

2017-02-16 19:39 267 查看

3800: Saber VS Lancer

Time Limit: 1 Sec  Memory Limit: 64 MB
Submit: 71  Solved: 27

[Submit][Status][Discuss]

Description

铁人三项是一种运动项目,和字面意思一样,是让铁做的人(?)去做三个项目,必须连续完成,而且全程讲求速度。第一项是游泳,第二项是骑自行车,第三项是跑步。现在所有选手的三个项目的速度都是已知的。但是这次比赛中,裁判可以任意选择每一个项目的路程长度(假设没有一项长度为0)。但是这样显然会影响比赛排名……有时她会按某种方式选择,使得一些个别的选手能赢得竞赛。

Input

首行为运动员的人数N (1 ≤ N ≤ 100,80%的数据中n<=20),以下N行,每行含3个整数,Vi, Ui 和Wi (1 ≤ Vi, Ui, Wi ≤ 10000),用空格隔开,表示各人3个项目的速度。 

Output

对于每个运动员,都用一行输出,假如裁判以某种方式选择的路程会使得他赢(即第一个冲线,同时抵达不算赢),则输出“Yes”,否则输出“No”  。

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

HINT

Source



[Submit][Status][Discuss]

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

#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
,p
,tmp
;
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
;
double a
,b
,c
;
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()
{
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");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: