POJ 1151
2014-04-30 18:36
387 查看
思路:首先将横坐标离散化,再对纵坐标排序,然后根据y轴从下往上扫描,每次的高度就是seg[i].y-seg[i-1].y,这就相当于分矩形的宽,然后要做的事就是查询x轴(矩形长)的有效长度,这就要交给线段树了。
/************************************************************************* > File Name: area.cpp > Author: wangzhili > Mail: wangstdio.h@gmail.com > Created Time: 2014/3/1 星期六 16:06:57 ************************************************************************/ #include<iostream> #include<algorithm> #include<cstdio> #define MAX 1000 using namespace std; class TreeNode { public: int left; int right; int mid; int cover; int flag; double length; }; typedef struct { double xl, xr, y; int flag; }Line; TreeNode node[3*MAX]; Line seg[MAX]; double x[MAX]; double length; bool cmp(Line a, Line b) { return a.y < b.y; } void BuildTree(int k, int l, int r) { node[k].left = l; node[k].right = r; node[k].mid = (l + r) >> 1; node[k].cover = 0; node[k].flag = 0; if(l + 1 == r) { node[k].flag = 1; return ; } int mid = (l + r) >> 1; BuildTree(k << 1, l, mid); BuildTree(k << 1|1, mid, r); } void UpdateTree(int k, int l, int r, int flag) { if(node[k].left == l && node[k].right == r) { node[k].cover += flag; node[k].length = x[r-1] - x[l-1]; return ; } if(node[k].flag) return ; if(node[k].mid <= l) UpdateTree(k << 1|1, l, r, flag); else if(node[k].mid >= r) UpdateTree(k << 1, l, r, flag); else { UpdateTree(k << 1, l, node[k].mid, flag); UpdateTree(k << 1|1, node[k].mid, r, flag); } } void GetLength(int k) { if(node[k].cover > 0) { length += node[k].length; return ; } if(node[k].flag) return; GetLength(k << 1); GetLength(k << 1|1); } int GetIndex(double num, int length) { int l, r, mid; l = 0, r = length-1; while(l <= r) { mid = (l + r) >> 1; if(x[mid] == num) return mid; else if(x[mid] > num) r = mid - 1; else l = mid + 1; } } int main(int argc, char const *argv[]) { int n, i, j, k, cnt; int xl, xr; double ans; double x1, y1, x2, y2; cnt = 0; BuildTree(1, 1, 205); // freopen("in.c", "r", stdin); while(~scanf("%d", &n) && n) { j = 0; ans = 0.; for(i = 1; i < 408; i ++) { node[i].cover = 0; } for(i = 0; i < n; i ++) { scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2); seg[j].xl = x1; seg[j].xr = x2; seg[j].y = y1; x[j] = x1; seg[j ++].flag = 1; seg[j].xl = x1; seg[j].xr = x2; seg[j].y = y2; x[j] = x2; seg[j ++].flag = -1; } sort(x, x+j); sort(seg, seg+j, cmp); k = 1; for(i = 1; i < j; i ++) { if(x[i] != x[i-1]) x[k ++] = x[i]; } xl = GetIndex(seg[0].xl, k) + 1; xr = GetIndex(seg[0].xr, k) + 1; UpdateTree(1, xl, xr, seg[0].flag); length = 0; GetLength(1); for(i = 1; i < j; i ++) { ans += (seg[i].y-seg[i-1].y)*length; xl = GetIndex(seg[i].xl, k)+1; xr = GetIndex(seg[i].xr, k)+1; UpdateTree(1, xl, xr, seg[i].flag); length = 0.; GetLength(1); } printf("Test case #%d\nTotal explored area: %.2lf\n\n", ++cnt, ans); } return 0; }