來自《挑戰程序設計競賽》
但是找到的題解和書上給的模板很不一樣……
題解參考了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;
}