bzoj 3800: Saber VS Lancer (半平面交求解不等式组)
2017-02-16 19:39
267 查看
3800: Saber VS Lancer
Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 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
910 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
YesYes
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");
}
}
相关文章推荐
- BZOJ 3800 Saber VS Lancer/POJ 1755 Triathlon 半平面交
- poj 1755 Triathlon (半平面交求解不等式组)
- 【BZOJ2005】【codevs1937】能量采集,数论练习之二维公约数求和
- BZOJ_P2049&Codevs_P1839 [SDOI2008]Cave 洞穴勘测(LCT)
- bzoj1038 瞭望塔 半平面交
- 【bzoj 1047】【codevs 1715】[HAOI2007]理想的正方形(单调队列)
- 【BZOJ1934】【codevs2341】善意的投票,二分图最小割
- 【BZOJ1079】【codevs2428】着色方案,DP
- BZOJ 1007 HNOI 2008 水平可见直线 半平面交
- 【BZOJ1038】【codevs1412】瞭望塔,半平面交/三分法
- 【BZOJ2754】【codevs2403】喵星球上的点名,AC自动机与STL的狂欢
- [半平面交对偶凸包] BZOJ 1007 [HNOI2008]水平可见直线
- BZOJ_P2729[HNOI2012]排队&Codevs_P1994 排队(数论)
- bzoj 1038: [ZJOI2008]瞭望塔 (半平面交)
- bzoj 3190: [JLOI2013]赛车 (半平面交)
- BZOJ_P1087&Codevs_P2451 [SCOI2005]互不侵犯King(状态压缩DP)
- bzoj1040&CodeVS1423 骑士
- bzoj4404 Binary vs Decimal
- BZOJ_P1407&Codevs_P1747 [NOI2002]Savage(数论+扩展欧几里得)
- [codevs4654][bzoj2442]修剪草坪(单调队列dp)