Aizu 0513 Paint Color【離散化+BFS】

題目鏈接 (日語題……(:зゝ∠)

題意

在直角座標系的第一象限中有一塊m*h的板子,在上面貼上了一些矩形的膠帶,現在告訴每個膠帶的左下座標和右上座標,求板子上有多少個不連通的空白區域(沒有貼膠帶)

分析

座標範圍太大,1e6左右,直接按座標來BFS顯然不可能。但考慮到膠帶數量只要1e3,可以根據膠帶的位置對座標離散化處理。

離散化方法

x和y分開處理(因爲互不影響)。把所有的x1,x2以及它們相鄰的座標(即x1-1,x1,x1+1)放到一個vector中,排個序並去重,再從頭到尾遍歷每一對x1,x2找到它們在這個vector中國的位置,得到的就是它們離散化過後的座標。

    for(int i=0;i<n;++i)
    {
        for(int j=-1;j<=1;++j)
        {
            a=c1[i]+j;b=c2[i]+j;
            if(a>=0&&a<len) v.push_back(a);
            if(b>=0&&b<len) v.push_back(b);
        }
    }
    sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());//去重
    for(int i=0;i<n;++i)
    {
        c1[i]=lower_bound(v.begin(),v.end(),c1[i])-v.begin();//找到新座標
        c2[i]=lower_bound(v.begin(),v.end(),c2[i])-v.begin();
    }

但注意,這個題是按座標給的膠帶的位置,可能座標相鄰但膠帶不相鄰。比如有一個膠帶的x2=3,另一個膠帶的x1=4,它們間顯然是有空位的,但離散化後x2+1和x1相等了,在離散化過後成了相同的座標。這個問題可以通過把每一個x2和y2都減1(因爲滿足x1<x2y1<y2 ,減一後不會使其消失)

處理後用BFS就很方便了。但注意這題用DFS會爆棧。

AC代碼

//Aizu 0531 Paint Color
//AC 2016-8-2 16:53:08
//Discretization
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <set>
#include <string>
#include <map>
#include <queue>
#include <deque>
#include <list>
#include <sstream>
#include <stack>
using namespace std;

#define cls(x) memset(x,0,sizeof x)
#define inf(x) memset(x,0x3f,sizeof x)
#define neg(x) memset(x,-1,sizeof x)
#define ninf(x) memset(x,0xc0,sizeof x)
#define st0(x) memset(x,false,sizeof x)
#define st1(x) memset(x,true,sizeof x)
#define INF 0x3f3f3f3f
#define lowbit(x) x&(-x)
#define bug cout<<"here"<<endl;
//#define debug

const int maxn=1005;
int w,h;
int n;
int X1[1005],X2[1005],Y1[1005],Y2[1005];
int G[3*maxn][3*maxn];
const int dx[]={1,-1,0,0};
const int dy[]={0,0,1,-1};

void compress(int c1[],int c2[],int &len)
{
    vector<int> v;
    int a,b;
    for(int i=0;i<n;++i)
    {
        for(int j=-1;j<=1;++j)
        {
            a=c1[i]+j;b=c2[i]+j;
            if(a>=0&&a<len) v.push_back(a);
            if(b>=0&&b<len) v.push_back(b);
        }
    }
    sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());
    for(int i=0;i<n;++i)
    {
        c1[i]=lower_bound(v.begin(),v.end(),c1[i])-v.begin();
        c2[i]=lower_bound(v.begin(),v.end(),c2[i])-v.begin();
    }
    len=v.size();
    return;
}

int main()
{
    #ifdef debug
        freopen("E:\\Documents\\code\\input.txt","r",stdin);
        freopen("E:\\Documents\\code\\output.txt","w",stdout);
    #endif
    while(cin>>w>>h&&w+h)
    {
        cin>>n;
        for(int i=0;i<n;++i)
        {
            cin>>X1[i]>>Y1[i]>>X2[i]>>Y2[i];
            --X2[i];--Y2[i];
        }
        compress(X1,X2,w);
        compress(Y1,Y2,h);
        cls(G);
        for(int i=0;i<n;++i)
            for(int x=X1[i];x<=X2[i];++x)
                for(int y=Y1[i];y<=Y2[i];++y)
                    G[y][x]=1;
        int ans=0;
        for(int y=0;y<h;++y)
        {
            for(int x=0;x<w;++x)
            {
                if(G[y][x]) continue;
                G[y][x]=1;
                ++ans;
                int xx,yy,nx,ny;
                queue<pair<int,int> > BFS;
                BFS.push(make_pair(x,y));
                while(BFS.size())
                {
                    int yy=BFS.front().second,xx=BFS.front().first;
                    BFS.pop();
                    for(int k=0;k<4;++k)
                    {
                        nx=xx+dx[k];ny=yy+dy[k];
                        if(nx>=0&&nx<w&&ny>=0&&ny<h&&!G[ny][nx])
                        {
                            BFS.push(make_pair(nx,ny));
                            G[ny][nx]=1;
                        }
                    }
                }
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}
發佈了54 篇原創文章 · 獲贊 3 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章