题目:http://poj.org/problem?id=1151 题意:求矩形并的面积 思路:线段树+离散化+扫描线#include <stdio.h> #include <algorithm> #include <iostream> #include <math.h> using namespace std; const int maxn=200; struct SegmentTree { int l, r, cover; double len, sum; }st[maxn<<2]; struct line { double y_top, y_btm, x; int in; bool operator<(line l) const { return x<l.x; } }l[maxn+10]; int n, cnt; double y[maxn+10], ans, last_area; void BuildTree(int v, int left, int right) { st[v].l=left, st[v].r=right, st[v].cover=0, st[v].len=y[right]-y[left]; if (right-left==1) { st[v].sum=0; return; } int mid=(left+right)>>1; int lc=v<<1; int rc=lc+1; BuildTree(lc, left, mid); BuildTree(rc, mid, right); st[v].sum=st[lc].sum+st[rc].sum; } void Update(int v) { if (st[v].cover>0) st[v].sum=st[v].len; else if (st[v].r-st[v].l>1) st[v].sum=st[v*2].sum+st[v*2+1].sum; else st[v].sum=0; } void Insert(int v, int left, int right) { if (st[v].l==left&&st[v].r==right) st[v].cover++; else { int lc=v<<1; int rc=lc+1; int mid=(st[v].l+st[v].r)>>1; if (right<=mid) Insert(lc, left, right); else if (left>=mid) Insert(rc, left, right); else { Insert(lc, left, mid); Insert(rc, mid, right); } } Update(v); } void Delete(int v, int left, int right) { if (st[v].l==left&&st[v].r==right) st[v].cover--; else { int lc=v<<1; int rc=lc+1; int mid=(st[v].l+st[v].r)>>1; if (right<=mid) Delete(lc, left, right); else if (left>=mid) Delete(rc, left, right); else { Delete(lc, left, mid); Delete(rc, mid, right); } } Update(v); } int GetIndex(double x) { return lower_bound(y, y+cnt, x)-y; } int main() { //freopen("in.txt", "r", stdin); int cc=1; while (scanf("%d", &n), n) { double x1, y1, x2, y2; for (int i=0; i<n; i++) { scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2); l[i*2].x=x1, l[i*2+1].x=x2; l[i*2].y_top=l[i*2+1].y_top=y1; l[i*2].y_btm=l[i*2+1].y_btm=y2; l[i*2].in=1, l[i*2+1].in=0; y[i*2]=y1, y[i*2+1]=y2; } sort(y, y+2*n); sort(l, l+2*n); cnt=0; for (int i=1; i<2*n; i++) { if (y[i]!=y[i-1]) y[cnt++]=y[i-1]; } y[cnt++]=y[2*n-1]; BuildTree(1, 0, cnt-1); ans=0; for (int i=0; i<2*n-1; i++) { if (l[i].in) Insert(1, GetIndex(l[i].y_top), GetIndex(l[i].y_btm)); else Delete(1, GetIndex(l[i].y_top), GetIndex(l[i].y_btm)); ans+=(l[i+1].x-l[i].x)*st[1].sum; } printf("Test case #%d\n", cc++); printf("Total explored area: %.2lf\n\n", ans); } return 0; }
PKU 1151 Atlantis
最新推荐文章于 2014-01-20 21:11:55 发布