hdu 2297 Run 半平面交
来源:互联网 发布:淘宝澳洲站 编辑:程序博客网 时间:2024/05/29 18:44
题意:
在一条笔直的路上进行赛跑,给出n个运动员的初始坐标和速度大小,假设所有人都会不停地跑,问有都少人可能在某时刻成为第一。
解:
以初始位置为纵坐标,速度为斜率,构造射线。进行半平面交,每条射线的左方为所求部分,现在要找出所求部分的边缘线。
#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>#include<vector>using namespace std;#define all(x) (x).begin(), (x).end()#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)#define mes(a,x,s) memset(a,x,(s)*sizeof a[0])#define mem(a,x) memset(a,x,sizeof a)#define ysk(x) (1<<(x))typedef long long ll;typedef pair<int, int> pii;const int INF =0x3f3f3f3f;const int maxn= 50000 ;const double PI=cos(-1.0);const double eps=1e-10;int dcmp(double x){ if(fabs(x)<eps) return 0; else return x<0?-1:1;}struct Point{ double x,y; Point(double x=0,double y=0):x(x),y(y) {}; bool operator ==(const Point B)const {return dcmp(x-B.x)==0&&dcmp(y-B.y)==0;} bool operator<(const Point& b)const { return dcmp(x-b.x)<0|| dcmp(x-b.x)==0 &&dcmp(y-b.y)<0; }}poly[maxn+10];typedef Point Vector;Vector operator -(Vector A,Vector B) {return Vector(A.x-B.x,A.y-B.y); }double Cross(Vector A,Vector B)//叉乘{ return A.x*B.y-A.y*B.x;}double Dot(Vector A,Vector B)//点乘{ return 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 p) {return Vector(A.x*p,A.y*p); }Point GetLineIntersection(Point P,Vector v,Point Q,Vector w)//点线式{ Vector u=P-Q; double t=Cross(w,u)/Cross(v,w); return P+v*t;}struct Line{ Point p,p2; Vector v; double ang; Line(){} Line(Point a,Vector v):p(a),v(v){ang=atan2(v.y,v.x); }//点线式 void twoPointIntial(Point p,Point p2)//两点式 { this->p=p; this->p2=p2; v= p2-p; ang=atan2(v.y,v.x); } bool operator<(const Line & L)const { return ang<L.ang; }}L[maxn+10];typedef Line Seg;Point GetIntersection(Line a,Line b){ Vector u=a.p-b.p; double t=Cross(b.v,u)/Cross(a.v,b.v); return a.p+a.v*t;}bool OnLeft(Line L,Point p){ return Cross(L.v,p-L.p)>0;}Point p[maxn+5];Line q[maxn+5];int HalfplaneIntersection(Line* L,int n,Point * poly){ sort(L,L+n); 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(fabs(Cross(q[last].v,q[last-1].v) )<eps ) { last--; if(OnLeft(q[last],L[i].p) ) q[last]=L[i]; } if(first<last) p[last-1]=GetIntersection(q[last-1],q[last] ); } while(first<last&&!OnLeft(q[first],p[last-1])) last--; if(last-first<=1) return 2; p[last]=GetIntersection(q[last],q[first]); int m=0; for(int i=first;i<=last;i++) poly[m++]=p[i]; return m;}int main(){ std::ios::sync_with_stdio(false); int T,n;cin>>T; while(T--) { cin>>n; for0(i,n) { double p,sp; cin>>p>>sp; L[i]=Line(Point(0,p),Vector(1,sp)); } L[n++].twoPointIntial(Point(0,0),Point(0,-INF)); int m=HalfplaneIntersection(L,n,poly); printf("%d\n",m-1); } return 0;}/*111 1*/
最后减去1,是为了减去新增加的1条边。在此题进行半平面角后的结果集合中,有多少个点正好就对应多少条边。
0 0
- hdu 2297 Run 半平面交
- HDU 2297 半平面交
- hdu 4327 简单立体几何 + 半平面交
- hdu - 4327 - Shooting - 立体几何 + 半平面交
- hdu 5462 Manors(半平面交)
- HDU 3761 (二分 半平面交)
- HDU 3982 半平面交+圆与多边形面积交
- HDU 3982 (半平面交 多边形和圆面积交)
- pku2451 半平面交
- 半平面交
- 半平面交
- poj2540 半平面交
- 半平面交
- poj2451 半平面交
- 半平面交.....
- 半平面交
- POJ3384+半平面交
- HDU1632+半平面交
- java exception 和 runtimeException的区别
- EL表达式
- mysql EF6.0 报错:“ Guid 字符串只应包含十六进制字符。”
- Windows RPC 远程过程调用
- 子序列最大和
- hdu 2297 Run 半平面交
- 数组类小案例(重载 '[]' '=' '==' 和 '!=' 运算符)(进阶4)
- ZZULIOJ 1914 天火好帅
- GPUImage中是如果保存OpenGL渲染后的视频的
- MongoDB学习(一)初识NoSql及MongoDB
- 谈谈Material Design之CoordinatorLayout
- Bean Validation 技术规范特性概述
- 响应式和自适应的区别
- [Codeforces 272E] Dima and Horses (图染色构造)