【POJ】2043.Area of Polygons

原题戳这里
开始一小段时间的POJ计算几何练习计划(估计很快就会被恶心回去)

题解

用一条平行于y轴的扫描线,计算两条扫描线之间多少格子被覆盖了
精度可tm变态了,可能是因为题目要求的关系吧,需要上取整和下取整,可能有一点误差也给算进去了,精度掉的很大
看一下上一次的上边界是哪里,不要重复计算

代码

#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#include <cstring>
#include <ctime>
#include <map>
#include <algorithm>
#include <cmath>
#define MAXN 100005
#define eps 1e-8
//#define ivorysi
#define PDD pair<db,db>
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long int64;
typedef double db;
int N;
bool dcmp(db a,db b) {
	return fabs(a - b) < eps;
}
bool Gter(db a,db b) {
	return a > b + eps;
}
struct Point {
	db x,y;
	Point() {}
	Point(db _x,db _y) {
		x = _x;y = _y;
	}
	friend Point operator + (const Point &a,const Point &b) {
		return Point(a.x + b.x,a.y + b.y);
	}
	friend Point operator - (const Point &a,const Point &b) {
		return Point(a.x - b.x,a.y - b.y);
	}
	friend Point operator / (const Point &a,const db &k) {
		return Point(a.x / k,a.y / k);
	}
	friend Point operator * (const Point &a,const db &k) {
		return Point(a.x * k,a.y * k);
	}
	friend db operator * (const Point &a,const Point &b) {
		return a.x * b.y - a.y * b.x;
	}
}P[205];
db dot(Point a,Point b) {
	return a.x * b.x + a.y * b.y; 
}
struct Seg {
	Point a,b;
	Seg() {}
	Seg(Point _a,Point _b) {
		a = _a;b = _b;
	}
}Line[205];
PDD Y[205];

void Solve() {
	int ans = 0;
	int st = 2000,ed = -2000;
	for(int i = 1 ; i <= N ; ++i) {
		scanf("%lf%lf",&P[i].x,&P[i].y);
		st = min(st,(int)P[i].x);
		ed = max(ed,(int)P[i].x);
	}
	P[N + 1] = P[1];
	for(int i = 1 ; i <= N ; ++i) {
		if(P[i].x > P[i + 1].x) Line[i] = Seg(P[i + 1],P[i]);
		else Line[i] = Seg(P[i],P[i + 1]);
	}
	for(int i = st ; i <= ed ; ++i) {
		int cnt = 0;
		for(int j = 1 ; j <= N ; ++j) {
			if(Line[j].a.x <= i && Line[j].b.x >= i + 1) {
				db a = Line[j].a.y + (i - Line[j].a.x) * (Line[j].b.y - Line[j].a.y) / (Line[j].b.x - Line[j].a.x);
				db b = Line[j].a.y + (i - Line[j].a.x + 1) * (Line[j].b.y - Line[j].a.y) / (Line[j].b.x - Line[j].a.x);
				Y[++cnt] = mp(a,b);
			}
		}
		sort(Y + 1,Y + cnt + 1);
		int last = -4001;
		for(int j = 1 ; j <= cnt ; j += 2) {
			int f = floor(min(Y[j].fi,Y[j].se));
			int c = ceil(max(Y[j + 1].fi,Y[j + 1].se));
			f = max(f,last);
			ans += c - f;
			last = c;
		}
	}
	printf("%d
",ans);
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    while(scanf("%d",&N) != EOF && N) {
    	Solve();
	}
    return 0;
}
原文地址:https://www.cnblogs.com/ivorysi/p/8993870.html