计算几何是个有些许麻烦的专题 , 因为即使是算法对了 , 精度问题也是不可忽视的 , 调试会有些麻烦......
提示:
1. 是一个有点裸的半平面交的题目 , 不需要用O(nlogn)复杂度的算法
2. 你可以先写写白书上的一个CurPolygon的函数(在半平面交的最开始处)
如果你完全那样写估计就会得到WA , 我就是这么干的 , 但并不要紧 , 因为你可能和我一样就只有一个地方有问题
强烈建议先自己尝试调错(想想我刚开始的抱怨), 下面我给出代码 , 在代码后我会解释精度问题的原因(其实书上提笔带过):
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <string> #include <vector> #include <deque> #include <stack> #include <algorithm> using namespace std; double eps = 1e-10; int dcmp(double a){ return fabs(a)<eps?0:(a<0?-1:1); } struct points { double x , y; void read(){ cin>>x>>y; } points(double x = 0 , double y = 0):x(x),y(y){} bool operator <(const points& b)const { return dcmp(x-b.x)<0 || (dcmp(x-b.x)==0 && dcmp(y-b.y)<0); } }; typedef points Vector; typedef vector<points> Polygon; 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 b) { return Vector(a.x*b , a.y*b ); } Vector operator /(Vector a , double b) { return Vector(a.x/b , a.y/b ); } bool operator ==(Vector a , Vector b) { return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0; } bool operator !=(Vector a , Vector b) { return dcmp(a.x-b.x) || dcmp(a.y-b.y); } double Dot(Vector a , Vector b) { return a.x*b.x+a.y*b.y; } double Cross(Vector a , Vector b) { return a.x*b.y-a.y*b.x; } double Length(Vector a) { return sqrt(Dot(a, a)); } double angle(Vector a){ return atan2(a.y, a.x); } double angle(Vector a , Vector b) { return acos(Dot(a, b)/Length(a)/Length(b)); } Polygon p , ne; points a[2000]; points LinesIntersection(points p , Vector v , points q , Vector w) { Vector u = p-q; double t = Cross(w, u)/Cross(v, w); return p+v*t; } bool OnSegment(points p , points a , points b) { return dcmp(Dot(a-p, b-p))<0; } Polygon CutAPolygon(points a , points b , Polygon p) { int n = (int)p.size(); ne.clear(); for(int i=0;i<p.size();i++) { points c = p[i]; points d = p[(i+1)%n]; if(dcmp(Cross(b-a, c-a))>=0) ne.push_back(c); if(dcmp(Cross(b-a, c-d))) { points e = LinesIntersection(a, b-a, c, d-c); if(OnSegment(e, c, d)) ne.push_back(e); } } return ne; } double PolygonArea(Polygon p) { double res = 0; int n = (int)p.size(); for(int i=1;i<n-1;i++) res+= Cross(p[i]-p[0], p[(i+1)]-p[0]); return res/2.0; } int main(int argc, char *argv[]) { int t , n; cin>>t; while(t-- && cin>>n) { for(int i=0;i<n;i++) a[i].read(); for(int i=0;i<n;i++) p.push_back(a[i]); if(PolygonArea(p)<0) { reverse(a, a+n); reverse(p.begin(), p.end()); } for(int i=0;i<n;i++) p = CutAPolygon(a[i], a[(i+1)%n], p); printf("%.2lf\n",fabs(PolygonArea(p))); } return 0; }
PS: 貌似博主的正确程序被弄掉了 , 这个程序不一定是正确的 , 但是稍稍修改初始化半平面的代码就可以了 , (也就是初始的那个平面不用题目给的多边形,而是自己加一个很大的矩形) , 或者联系我讨论: QQ 812483101