poj 2540 Hotter Colder 半平面交
2016-08-23 21:27
429 查看
题目链接
题意:
在一个(0,0) ,(10,0),(10,10),(0,10)四个点围成的正方形房屋内藏着一个人B,现在A蒙着眼从(0,0)出发,之后经过一些点停下,B会告诉他这个位置和上一次比是距自己近了,还是远了。每一步输出B可能所在区域的面积。
解法:
首先一点,如果是”Same”,那么之后都输出0.00 。每一步半平面交之后求凸多边形面积。
对于两个连续的停留点A、B,首先确定中点midP,然后v⃗ =AB−→−,之后根据(x,y)∗(y,−x)=0,将v⃗ =(v.y,−v.x),这就求出了中垂线方向上的向量。
我们假定是Colder,那么A点必然在v⃗ 左边,所以直接判断A点v⃗ 是否在左边,如果不是调换v⃗ 的方向,那么现在A点必然在v⃗ 左边,如果这时发现是Hotter,那么再次调换v⃗ 的方向。
这样midP和v⃗ 就构成了一条射线(一个半平面)。
代码:
#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= 100 ; const double PI=acos(-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; } }; 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); } Vector operator /(Vector A,double p) {return Vector(A.x/p,A.y/p); } Vector operator -(Vector A) {return Vector(-A.x,-A.y);} 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); } Point point(double t)//参数方程求参数t对应点 { return p+v*t; } bool operator<(const Line & L)const { return ang<L.ang; } }; 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 OnRight(Line L,Point p) { return dcmp(Cross(L.v,p-L.p))<0; } int HalfplaneIntersection(Line* L,int n,Point * poly) { sort(L,L+n); int first,last; Point *p=new Point ; Line *q=new Line ; q[first=last=0]=L[0]; for(int i=1;i<n;i++) { while(first<last&&OnRight(L[i],p[last-1] ) ) last--; while(first<last&&OnRight(L[i],p[first])) first++; q[++last]=L[i]; if(fabs(Cross(q[last].v,q[last-1].v) )<eps ) { last--; if(!OnRight(q[last],L[i].p) ) q[last]=L[i]; } if(first<last) p[last-1]=GetIntersection(q[last-1],q[last] ); } while(first<last&&OnRight(q[first],p[last-1])) last--; if(last-first<=1) return 0;//小于3个,不存在 p[last]=GetIntersection(q[last],q[first]); int m=0; for(int i=first;i<=last;i++) poly[m++]=p[i]; return m; } double PolygonArea(Point *p,int n) { double area=0; for(int i=1;i<n-1;i++) { area+=Cross(p[i]-p[0],p[i+1]-p[0]); } return area/2; } Point getMidPoint(Point a,Point b) { return Point( (a.x+b.x)/2,(a.y+b.y)/2 ); } int n,np; Line L[maxn+10]; Point p[maxn+10],poly[maxn+10]; string s; int main() { std::ios::sync_with_stdio(false); double x,y; bool zero=0;n=0; L[n++].twoPointIntial(Point(0,0),Point(10,0)); L[n++].twoPointIntial(Point(10,0),Point(10,10)); L[n++].twoPointIntial(Point(10,10),Point(0,10)); L[n++].twoPointIntial(Point(0,10),Point(0,0)); np=1; while(cin>>p[np].x>>p[np].y) { cin>>s; if(s=="Same") zero=1; Vector v=p[np]-p[np-1]; v=Vector(v.y,-v.x); Point midP=getMidPoint(p[np],p[np-1]); if(dcmp(Cross(v,p[np-1]-midP ) )<0 ) v=-v; if(s=="Hotter") v=-v; L[n++]=Line( midP,v); if(zero) { puts("0.00"); } else { int m=HalfplaneIntersection(L,n,poly); double s=PolygonArea(poly,m); if(dcmp(s)==0 ) puts("0.00"); else printf("%.2f\n",s); } np++; } return 0; }
#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= 100 ; const double PI=acos(-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; } }; 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); } Vector operator /(Vector A,double p) {return Vector(A.x/p,A.y/p); } Vector operator -(Vector A) {return Vector(-A.x,-A.y);} 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); } Point point(double t)//参数方程求参数t对应点 { return p+v*t; } bool operator<(const Line & L)const { return ang<L.ang; } }; 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 OnRight(Line L,Point p) { return dcmp(Cross(L.v,p-L.p))<0; } int HalfplaneIntersection(Line* L,int n,Point * poly) { sort(L,L+n); int first,last; Point *p=new Point ; Line *q=new Line ; q[first=last=0]=L[0]; for(int i=1;i<n;i++) { while(first<last&&OnRight(L[i],p[last-1] ) ) last--; while(first<last&&OnRight(L[i],p[first])) first++; q[++last]=L[i]; if(fabs(Cross(q[last].v,q[last-1].v) )<eps ) { last--; if(!OnRight(q[last],L[i].p) ) q[last]=L[i]; } if(first<last) p[last-1]=GetIntersection(q[last-1],q[last] ); } while(first<last&&OnRight(q[first],p[last-1])) last--; if(last-first<=1) return 0;//小于3个,不存在 p[last]=GetIntersection(q[last],q[first]); int m=0; for(int i=first;i<=last;i++) poly[m++]=p[i]; return m; } double PolygonArea(Point *p,int n) { double area=0; for(int i=1;i<n-1;i++) { area+=Cross(p[i]-p[0],p[i+1]-p[0]); } return area/2; } Point getMidPoint(Point a,Point b) { return Point( (a.x+b.x)/2,(a.y+b.y)/2 ); } int n,np; Line L[maxn+10]; Point p[maxn+10],poly[maxn+10]; string s; int main() { std::ios::sync_with_stdio(false); double x,y; bool zero=0;n=0; L[n++].twoPointIntial(Point(0,0),Point(10,0)); L[n++].twoPointIntial(Point(10,0),Point(10,10)); L[n++].twoPointIntial(Point(10,10),Point(0,10)); L[n++].twoPointIntial(Point(0,10),Point(0,0)); np=1; while(cin>>p[np].x>>p[np].y) { cin>>s; if(s=="Same") zero=1; Vector v=p[np]-p[np-1]; v=Vector(v.y,-v.x); Point midP=getMidPoint(p[np],p[np-1]); if(dcmp(Cross(v,p[np-1]-midP ) )<0 ) v=-v; if(s=="Hotter") v=-v; L[n++]=Line( midP,v); if(zero) { puts("0.00"); } else { int m=HalfplaneIntersection(L,n,poly); double s=PolygonArea(poly,m); if(!m||dcmp(s)==0 ) puts("0.00"); else printf("%.2f\n",s); } np++; } return 0; }
相关文章推荐
- POJ 2540 Hotter Colder 半平面交 求可行域面积
- POJ 2540 Hotter Colder 半平面交 求可行域面积
- POJ 2540 Hotter Colder(半平面交)
- POJ 2540 Hotter Colder --半平面交
- poj 2540 && uva 10084 Hotter Colder(半平面交)
- POJ 2540 Hotter Colder(半平面交求可行域)
- POJ 2540 Hotter Colder(半平面交)
- POJ 2540 Hotter Colder(半平面交)
- poj 2540 Hotter Colder(极角计算半平面交)
- POJ 2540 ZOJ 1886 Hotter Colder 半平面交
- poj 2540 Hotter Colder 半平面交 不等式求区域面积
- poj 2540 Hotter Colder 切割多边形
- POJ 2540 Hotter Colder 笔记
- poj 2540 Hotter Colder(线性规划可行区域)
- POJ 2540 Hotter Colder
- poj 2540 Hotter Colder
- zoj 1886 || poj 2540 || UVA 10084 Hotter Colder
- POJ 2540 Hotter Colder
- POJ 2540 半平面交
- POJ 2540 Hotter Colder