AOJ0531(imos-累積和法)

來自《挑戰程序設計競賽》

但是找到的題解和書上給的模板很不一樣……

題解參考了http://www.hankcs.com/program/algorithm/aoj-0531-paint-color.html

給出題目的鏈接http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0531

突然發現,寫博客好麻煩,尤其是要做表格什麼的╮(╯_╰)╭

AC代碼:

#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<string>
#include<set>
#include<vector>
#include<cmath>
#include<bitset>
#include<stack>
#include<sstream>
using namespace std;
#define INF 0x7fffffff
const int maxn=1005;

int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};

int W,H,N;
int X1[maxn],X2[maxn],Y1[maxn],Y2[maxn];

//填充用
int fld[2*maxn][2*maxn];

//對x1和x2進行座標離散化
//返回離散化之後的寬度
int compress(int *x1,int *x2,int w)
{
    vector<int> xs;

    for(int i=0;i<N;i++){
        int tx1=x1[i];
        int tx2=x2[i];
        if(1<=tx1&&tx1<w) xs.push_back(tx1);
        if(1<=tx2&&tx2<w) xs.push_back(tx2);
    }
    xs.push_back(0);
    xs.push_back(w);

    //排序去重
    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()-1;
}

//寬度優先搜索
//求區域的個數
int bfs()
{
    int ans=0;
    for(int y=0;y<H;y++){
        for(int x=0;x<W;x++){
            if(fld[y][x]) continue;
            ans++;

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

                for(int i=0;i<4;i++){
                    int tx=sx+dx[i];
                    int ty=sy+dy[i];
                    if(tx<0||tx>W||ty<0||ty>H) continue;
                    if(fld[ty][tx]>0) continue;
                    que.push(make_pair(tx,ty));
                    fld[ty][tx]=1;
                }
            }
        }
    }
    return ans;
}
void solve()
{
    memset(fld,0,sizeof(fld));

    //座標離散化
    W=compress(X1,X2,W);
    H=compress(Y1,Y2,H);

    //imos法
    for(int i=0;i<N;i++){
        fld[Y1[i]][X1[i]]++;
        fld[Y1[i]][X2[i]]--;
        fld[Y2[i]][X1[i]]--;
        fld[Y2[i]][X2[i]]++;
    }

    //橫向累積
    for(int i=0;i<H;i++){
        for(int j=1;j<W;j++){
            fld[i][j]+=fld[i][j-1];
        }
    }

    //縱向累積
    for(int i=1;i<H;i++){
        for(int j=0;j<W;j++){
            fld[i][j]+=fld[i-1][j];
        }
    }
    //累積完後,fld非0部分表示有擋板
    cout<<bfs()<<endl;
}

int main()
{
    while(scanf("%d%d",&W,&H)==2){
        if(W==0&&H==0) break;
        scanf("%d",&N);
        for(int i=0;i<N;i++){
            scanf("%d%d%d%d",&X1[i],&Y1[i],&X2[i],&Y2[i]);
        }
        solve();
    }
    return 0;
}



發佈了119 篇原創文章 · 獲贊 16 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章