->题目请戳这里<-
题目大意:一个二维平面内有一些矩形,坐标范围0-100;求覆盖的1*1单位面积的个数,重复覆盖的算1次。
题目分析:可以用经典的一维线段树+扫描线求面积并,但此题数据量太小,0-100,而且都是整点,所以二维线段树直接水过。
详情请见代码:
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 105; struct node { int num; int area; int tree[N<<2]; void build(int num,int s,int e) { tree[num] = 0; if(s == e) return; int mid = (s + e)>>1; build(num<<1,s,mid); build(num<<1|1,mid + 1,e); } void insert(int num,int s,int e,int l,int r) { if(tree[num] == e - s + 1) return; if(s == l && e == r) { tree[num] = e - s + 1; return; } int mid = (s + e)>>1; if(r <= mid) insert(num<<1,s,mid,l,r); else { if(l > mid) insert(num<<1|1,mid + 1,e,l,r); else { insert(num<<1,s,mid,l,mid); insert(num<<1|1,mid + 1,e,mid + 1,r); } } tree[num] = tree[num<<1] + tree[num<<1|1]; } }seg[N<<2]; void build(int num,int s,int e) { seg[num].num = seg[num].area = 0; seg[num].build(1,1,101); if(s == e) return; int mid = (s + e)>>1; build(num<<1,s,mid); build(num<<1|1,mid + 1,e); } void insert(int num,int s,int e,int x1,int x2,int y1,int y2) { if(s == e) { seg[num].insert(1,1,101,y1,y2); seg[num].num = seg[num].tree[1]; return; } int mid = (s + e)>>1; if(x2 <= mid) insert(num<<1,s,mid,x1,x2,y1,y2); else { if(x1 > mid) insert(num<<1|1,mid + 1,e,x1,x2,y1,y2); else { insert(num<<1,s,mid,x1,mid,y1,y2); insert(num<<1|1,mid + 1,e,mid + 1,x2,y1,y2); } } seg[num].num = seg[num<<1].num + seg[num<<1|1].num; } int main() { int x1,x2,y1,y2,i; build(1,1,101); while(~scanf("%d%d%d%d",&x1,&y1,&x2,&y2)) { if(x1 == -2 && y1 == -2 && x2 == -2 && y2 == -2) { printf("%d\n",seg[1].num); break; } if(x1 == -1 && x2 == -1 && y1 == -1 && y2 == -1) { printf("%d\n",seg[1].num); build(1,1,101); } else { if(x1 > x2) { x1 ^= x2; x2 ^= x1; x1 ^= x2; } if(y1 > y2) { y1 ^= y2; y2 ^= y1; y1 ^= y2; } x1 ++;x2 ++;y1 ++;y2 ++; insert(1,1,101,x1,x2 - 1,y1,y2 - 1); } } return 0; } //31MS 712K