哇塞,一道野生的计算几何题诶,题目还看错了两次,一开始以为要求半平面交,后来发现直接暴力枚举就行了。
要注意矩形的四个角都是real number!还有多边形不一定是凸多边形!
计算每个点的期望,首先判断该点是否在多边形内,如果是,需要知道这个点+-0.5的小矩形与大矩形的交的面积,然后根据Ax+By算一下就行了。
#include <cstdio> #include <cstring> #include <cctype> #include <cstdlib> #include <ctime> #include <climits> #include <cmath> #include <iostream> #include <string> #include <vector> #include <set> #include <map> #include <list> #include <queue> #include <stack> #include <deque> #include <algorithm> 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-6; bool operator < (const Point &a, const Point &b) {return a.x < b.x || (a.x == b.x && a.y <b.y);} int dcmp(int x) {if (fabs(x)<eps) return 0; else return x < 0 ? -1 : 1;} bool operator == (const Point &a, const Point &b) {return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0;} 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);} int Dot(Vector A, Vector B) {return A.x*B.x + A.y*B.y;} int Cross(Vector A, Vector B) {return A.x*B.y - A.y*B.x;} bool OnSegment(Point P, Point A, Point B) { return dcmp(Cross(A-P, B-P))==0 && dcmp(Dot(A-P, B-P))<=0; } int isPointInPolygon(Point P, Point *A, int n) { int w = 0; for (int i = 0; i < n; i++) { if (OnSegment(P, A[i], A[(i+1)%n])) return -1; int k = dcmp(Cross(A[(i+1)%n]-A[i], P-A[i])); int d1 = dcmp(A[i].y - P.y); int d2 = dcmp(A[(i+1)%n].y - P.y); if (k>0 && d1<=0 && d2>0) w++; if (k<0 && d2<=0 && d1>0) w--; } if (w != 0) return 1; return 0; } int n,A,B; double L,R,U,D; Point a[maxn],tmp; double ans; double f(Point p) { if (isPointInPolygon(p,a,n)) { double r=(min(p.x+0.5,R)-max(p.x-0.5,L))*(min(p.y+0.5,U)-max(p.y-0.5,D)); return r*(p.x*A+p.y*B); } return 0; } int main() { while (scanf("%lf%lf%lf%lf",&L,&D,&R,&U)==4) { scanf("%d%d%d",&n,&A,&B); for (int i=0;i<n;i++) scanf("%lf%lf",&a[i].x,&a[i].y); ans=0; for (double x=ceil(L);x<=R;x+=1.0) for (double y=ceil(D);y<=U;y+=1.0) { tmp=Point(x,y); ans+=f(tmp); } printf("%.3lf\n",ans/(R-L)/(U-D)); } return 0; }