当前位置: 代码迷 >> 综合 >> Paint Color Aizu - 0531(坐标离散化)
  详细解决方案

Paint Color Aizu - 0531(坐标离散化)

热度:68   发布时间:2024-01-31 11:41:21.0

题意:
W*H的白色平面,已有给出n个黑色矩形,求多少个白色连通块

思路:
白书原题
就是把每个直线上、直线上、直线下的用作计算,忽略其他点达到离散化的目的。
最后W,H的规模都不会很大,所以直接跑bfs或者dfs记录连通块即可

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>using namespace std;const int maxn = 1e3 + 7;
int W,H,N;
bool fld[maxn * 6][maxn * 6];
int X1[maxn],Y1[maxn],X2[maxn],Y2[maxn];
int dirx[] = {0,0,1,-1};
int diry[] = {1,-1,0,0};int compress(int *x1,int *x2,int w) {vector<int>vec;for(int i = 1;i <= N;i++) {for(int j = -1;j <= 1;j++) {int dx1 = x1[i] + j,dx2 = x2[i] + j;if(dx1 <= w && dx1 >= 1) vec.push_back(dx1);if(dx2 <= w && dx2 >= 1) vec.push_back(dx2);}}sort(vec.begin(),vec.end());vec.erase(unique(vec.begin(),vec.end()),vec.end());for(int i = 1;i <= N;i++) {x1[i] = find(vec.begin(),vec.end(),x1[i]) - vec.begin();x2[i] = find(vec.begin(),vec.end(),x2[i]) - vec.begin();}return (int)vec.size();
}int solve() {int ans = 0;W = compress(X1, X2, W);H = compress(Y1, Y2, H);memset(fld,false,sizeof(fld));for(int i = 1;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;}}}for(int i = 0;i < H;i++) {for(int j = 0;j < W;j++) {if(fld[i][j]) continue;ans++;fld[i][j] = true;queue<pair<int,int> >Q;Q.push({i,j});while(!Q.empty()) {pair<int,int>now = Q.front();Q.pop();for(int k = 0;k < 4;k++) {int dx = now.second + dirx[k];int dy = now.first + diry[k];if(dx < W && dx >= 0 && dy < H && dy >= 0) {if(fld[dy][dx]) continue;fld[dy][dx] = true;Q.push({dy,dx});}}}}}return ans;
}int main() {while(~scanf("%d%d",&W,&H) && W) {scanf("%d",&N);for(int i = 1;i <= N;i++) {scanf("%d%d%d%d",&X1[i],&Y1[i],&X2[i],&Y2[i]);X1[i]++;Y1[i]++;}printf("%d\n",solve());}return 0;
}
  相关解决方案