POJ 1389 Area of Simple Polygons(多矩形重叠面积==离散化)
http://poj.org/problem?id=1389
题意:
平面上有n个平行于坐标轴的矩形,问你他们的总面积是多少?重叠的面积只算一次.
分析:
典型的离散化题目,与POJ1151类似:
http://blog.csdn.net/u013480600/article/details/39322791
主要思想是:
本题可以用线段树扫描线做,不过终归还是用离散化的思想来做,下面直接离散化做.(未使用线段树)
假设输入的矩阵中共有num1个不同的x坐标和num2个不同的y坐标,那么整个二维平面就被分割成了(num1-1)*(num2-1)个小方格矩形.
我们只要看上面(num1-1)*(num2-1)个小方格矩形哪些被某个大矩形覆盖,哪些没有被任何一个大矩形覆盖即可.
我们令mp[i][j]=1表示以(x[i], y[j])点为左上角,以(x[i+1], y[j+1])点为右上角的那个小矩形被某个大矩形覆盖了.
假设大矩形I的x坐标范围在[xi,xj]之间而y坐标在[yk,yh]之间.那么该大矩阵I肯定使得 所有的mp[a][b]==1. 其中i<=a<k且j<=b<h.
AC代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=2000+5; struct Node { int x1,y1,x2,y2; }nodes[maxn]; int n; int x[maxn],y[maxn]; int num1,num2; bool mp[maxn][maxn]; int main() { while(scanf("%d%d%d%d",&nodes[0].x1,&nodes[0].y1,&nodes[0].x2,&nodes[0].y2)==4) { n=1; if(nodes[0].x1==-1)break; num1=num2=0; x[num1++]=nodes[0].x1; x[num1++]=nodes[0].x2; y[num2++]=nodes[0].y1; y[num2++]=nodes[0].y2; while(true) { scanf("%d%d%d%d",&nodes[n].x1,&nodes[n].y1,&nodes[n].x2,&nodes[n].y2); if(nodes[n].x1==-1)break; x[num1++]=nodes[n].x1; x[num1++]=nodes[n].x2; y[num2++]=nodes[n].y1; y[num2++]=nodes[n].y2; ++n; } int tt=1; sort(x,x+num1); sort(y,y+num2); num1=unique(x,x+num1)-x; num2=unique(y,y+num2)-y; memset(mp,0,sizeof(mp)); for(int i=0;i<n;++i) { int L_x=lower_bound(x,x+num1,nodes[i].x1)-x; int R_x=lower_bound(x,x+num1,nodes[i].x2)-x; int L_y=lower_bound(y,y+num2,nodes[i].y1)-y; int R_y=lower_bound(y,y+num2,nodes[i].y2)-y; for(int j=L_x;j<R_x;++j) for(int k=L_y;k<R_y;++k) mp[j][k]=true; } int ans=0; for(int i=0;i<num1;++i) for(int j=0;j<num2;++j) if(mp[i][j]) ans+=(x[i+1]-x[i])*(y[j+1]-y[j]); printf("%d\n",ans); } return 0; }