线性规划,半平面的交(铁人三项,LA 2218)
2017-02-02 15:09
507 查看
Vector(B,-A)
这个向量简直神奇。
无论A,B,C的符号关系如何,这个向量所代表的半平面总是对的。
一看到有三个比赛项目,所以就认为是三维的线性规划,然后就不会了。。。其实是二维的呀,最终的排名只跟各项比赛的比重有关,而跟具体的长度无关,所以知道两项的比重,自然就知道第三项的比重,所以就是二维的呀。。。看来真的不能熬夜,不能通宵,搞一次身体就差的不行,脑子都傻了。
然后精度问题的解决办法就是乘以一个较大的数,或者乘以公倍数以保证无小数。
求直线交点的函数又喜闻乐见地写错了。。。
代码
这个向量简直神奇。
无论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; }
相关文章推荐
- LA 3218 - Find the Border PSLG 平面直线区域划分
- LA 2218 (半平面交) Triathlon
- LA 2218 Triathlon .
- LA 2218 Triathlon(半平面交)
- POJ 2164 && LA 3218 Find the Border (Geometry, PSLG 平面直线图)
- LA 6263 The Dragon and the knights 平面划分 ,欧拉定理
- LA 2797 (平面直线图PLSG) Monster Trap
- 百度优化的“铁人三项”规则
- LA 2797 Monster Trap 平面直线图(PSLG) -
- LA 2218 半平面交
- 信息安全铁人三项比赛答案
- LA 2218 Triathlon (Geometry, Half Plane Intersection)
- UVA LA 2218 列出不等式整理成半平面的形式来求半平面交,注意特判
- LA 2297 平面直线图(PSLG)
- 任意一点X0到超平面S的距离以及拉格朗日乘子法(Lagrange Multiplier) 和KKT条件
- 铁人三项暂告一段落
- 【奥运场馆】铁人三项赛场
- LA 2797 平面区域dfs
- LA 3263 平面划分
- 平面上欧拉定理:poj 2284( LA 3263 ) That Nice Euler Circuit