您的位置:首页 > 其它

线性规划,半平面的交(铁人三项,LA 2218)

2017-02-02 15:09 507 查看
Vector(B,-A)

这个向量简直神奇。

无论A,B,C的符号关系如何,这个向量所代表的半平面总是对的。

一看到有三个比赛项目,所以就认为是三维的线性规划,然后就不会了。。。其实是二维的呀,最终的排名只跟各项比赛的比重有关,而跟具体的长度无关,所以知道两项的比重,自然就知道第三项的比重,所以就是二维的呀。。。看来真的不能熬夜,不能通宵,搞一次身体就差的不行,脑子都傻了。

然后精度问题的解决办法就是乘以一个较大的数,或者乘以公倍数以保证无小数。

求直线交点的函数又喜闻乐见地写错了。。。

代码

#include<bits/stdc++.h>
#define SUM (U[i]*V[i]*W[i]*U[j]*V[j]*W[j])
using namespace std;
const int maxn = 110;

struct Point
{
double x,y;
Point(double x=0,double y=0):x(x),y(y){}
};

typedef Point Vector;

const double eps = 1e-10;
int dcmp(double x)
{
if(fabs(x)<eps) return 0;
else return x<0?-1:1;
}

Point operator + (Point A,Vector B)
{
return Point(A.x+B.x,A.y+B.y);
}

Vector operator - (Point A,Point 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);
}

double Cross(Vector A,Vector B)
{
return A.x*B.y-A.y*B.x;
}

double angle(Vector V)
{
return atan2(V.y,V.x);
}

struct Line
{
Point P;
Vector V;
double ang;
Line(Point P=Point(),Vector V=Vector()):P(P),V(V)
{
ang=angle(V);
}
bool operator < (const Line &rhs) const
{
return ang<rhs.ang;
}
};

bool OnLeft(Line L,Point P)
{
return dcmp(Cross(L.V,P-L.P))>0;
}

Point GetLineInterSection(Line A,Line B)
{
Vector u=B.P-A.P;
double t=Cross(u,B.V)/Cross(A.V,B.V);
return A.P+A.V*t;
}

int GetHalfPlaneInterSection(Line* L,int n,Point* poly)
{
sort(L,L+n);
Point* p=new Point
;
Line* q=new Line
;
int first,last;
q[first=last=0]=L[0];
for(int i=1;i<n;i++)
{
while(first<last&&!OnLeft(L[i],p[last-1])) last--;
while(first<last&&!OnLeft(L[i],p[first])) first++;
q[++last]=L[i];
if(dcmp(Cross(q[last].V,q[last-1].V))==0)
{
last--;
if(OnLeft(q[last],L[i].P)) q[last]=L[i];
}
if(first<last) p[last-1]=GetLineInterSection(q[last],q[last-1]);
}
while(first<last&&!OnLeft(q[first],p[last-1])) last--;
if(last-first<=1) return 0;
p[last]=GetLineInterSection(q[last],q[first]);
int m=0;
for(int i=first;i<=last;i++) poly[m++]=p[i];
return m;
}

int N;
double U[maxn],V[maxn],W[maxn];
Line L[maxn];
Point poly[maxn];

int main()
{
while(scanf("%d",&N)==1&&N)
{
for(int i=0;i<N;i++)
scanf("%lf %lf %lf",&U[i],&V[i],&W[i]);
for(int i=0;i<N;i++)
{
bool ok=true;
int lc=0;
for(int j=0;j<N;j++) if(i!=j)
{
if(dcmp(U[j]-U[i])>=0&&dcmp(V[j]-V[i])>=0&&dcmp(W[j]-W[i])>=0)
{
ok=false;
break;
}
if(dcmp(U[j]-U[i])<=0&&dcmp(V[j]-V[i])<=0&&dcmp(W[j]-W[i])<=0) continue;
double A=SUM/W[i]+SUM/U[j]-SUM/U[i]-SUM/W[j];
double B=SUM/W[i]+SUM/V[j]-SUM/V[i]-SUM/W[j];
double C=SUM/W[j]-SUM/W[i];
L[lc++]=Line(Point(-C/A,0),Vector(B,-A));
}
if(ok)
{
L[lc++]=Line(Point(0,0),Vector(1,0));
L[lc++]=Line(Point(1,0),Vector(-1,1));
L[lc++]=Line(Point(0,1),Vector(0,-1));
int m=GetHalfPlaneInterSection(L,lc,poly);
if(m) ok=true;
else ok=false;
}
if(ok) puts("Yes");
else puts("No");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: