坐标离散化

#include<iostream>
#include<math.h>
#include<algorithm>
#include<stdio.h>
#include<vector>
#include<memory.h>
#include<queue>
#define INF 10000000

typedef long long ll;
using namespace std;
int W,H,N;
int X1[505],X2[505],Y1[505],Y2[505];
//填充用
bool fld[3005][3005];
const int dx[4]={0,0,-1,1};
const int dy[4]={1,-1,0,0};
//对x1和x2进行坐标离散化,并返回离散化之后的宽度
int compress(int *x1,int *x2,int w)
{
    vector<int> xs;
    for(int i=0;i<N;i++)
    {
        for(int d=-1;d<=1;d++)
        {
            int tx1=x1[i]+d,tx2=x2[i]+d;
            if(1<=tx1&&tx1<=w) xs.push_back(tx1);
            if(1<=tx2&&tx2<=w) xs.push_back(tx2);
        }
    }
    sort(xs.begin(),xs.end());
    xs.erase(unique(xs.begin(),xs.end()),xs.end());//删除重复元素
    for(int i=0;i<N;i++)
    {
        x1[i]=find(xs.begin(),xs.end(),x1[i])-xs.begin();
        x2[i]=find(xs.begin(),xs.end(),x2[i])-xs.begin();
    }
    return xs.size();
}
int main()
{
    cin>>W>>H>>N;
    for(int i=0;i<N;i++)
    {
        cin>>X1[i]>>X2[i]>>Y1[i]>>Y2[i];
    }
    //坐标离散化
    W=compress(X1,X2,W);
    H=compress(Y1,Y2,H);

    //填充有直线的部分
    memset(fld,0,sizeof(fld));
    for(int i=0;i<N;i++)
    {
        for(int y=Y1[i];y<=Y2[i];y++)
        {
            for(int x=X1[i];x<=X2[i];x++)
            {
                fld[y][x]=true;
            }
        }
    }

    //求区域的个数
    int ans=0;
    for(int y=0;y<H;y++)
    {
        for(int x=0;x<W;x++)
        {
            if(fld[y][x]) continue;
            ans++;

            //bfs
            queue<pair<int,int> > que;
            que.push(make_pair(x,y));
            while(!que.empty())
            {
                int sx=que.front().first,sy=que.front().second;
                que.pop();

                for(int i=0;i<4;i++)
                {
                    int tx=sx+dx[i],ty=sy+dy[i];
                    if(tx<0||tx>=W||ty<0||ty>=H) continue;
                    if(fld[ty][tx]) continue;
                    que.push(make_pair(tx,ty));
                    fld[ty][tx]=true;
                }
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}
/*
10 10 5
1 6 4 4
1 10 8 8
4 4 1 10
9 9 1 5
10 10 6 10
*/
//ans=6
View Code
原文地址:https://www.cnblogs.com/wangkaipeng/p/6503322.html