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;
}