POJ 1389 Area of Simple Polygons(多矩形重叠面积==离散化)

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

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值