読者です 読者をやめる 読者になる 読者になる

AOJ 1337 Count the Regions

問題概要

xy 平面に長方形が N 個与えられる.長方形によっていくつの領域に分かれるか求めよ.

・制約
1 <= N <= 50
長方形がある x, y 座標は 0 <= x, y <= 10^6

解法

N が小さいので座標圧縮と確信できる.
与えられた座標を2倍して持っておくと,幅が1しかない領域を数えるのが楽になる.(たとえば,3と4は2倍するとそれぞれ6と8になるので,3と4の間として7を使える.vectorで圧縮後の平面を持つのでこうしておくと便利.)

ソースコード

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
using P = pair<int, int>;

int main() {
    int n;
    while(cin >> n, n) {
        vector<int> xs, ys;
        vector<int> x1(4*n), x2(4*n), y1(4*n), y2(4*n);
        for(int i=0; i<n; ++i) {
            int l, t, r, b;
            cin >> l >> t >> r >> b;
            l *= 2; t *= 2; r *= 2; b *= 2;
            x1[i*4] = l, x2[i*4] = r, y1[i*4] = t, y2[i*4] = t;
            x1[i*4+1] = l, x2[i*4+1] = l, y1[i*4+1] = b, y2[i*4+1] = t;
            x1[i*4+2] = r, x2[i*4+2] = r, y1[i*4+2] = b, y2[i*4+2] = t;
            x1[i*4+3] = l, x2[i*4+3] = r, y1[i*4+3] = b, y2[i*4+3] = b;
            for(int j=-1; j<=1; ++j) {
                xs.push_back(l+j);
                xs.push_back(r+j);
                ys.push_back(t+j);
                ys.push_back(b+j);
            }
        }
        sort(xs.begin(), xs.end());
        sort(ys.begin(), ys.end());
        xs.erase(unique(xs.begin(), xs.end()), xs.end());
        ys.erase(unique(ys.begin(), ys.end()), ys.end());
        for(int i=0; i<4*n; ++i) {
            x1[i] = find(xs.begin(), xs.end(), x1[i]) - xs.begin();
            x2[i] = find(xs.begin(), xs.end(), x2[i]) - xs.begin();
            y1[i] = find(ys.begin(), ys.end(), y1[i]) - ys.begin();
            y2[i] = find(ys.begin(), ys.end(), y2[i]) - ys.begin();
        }
        int res = 0;
        vector<vector<bool>> fld(ys.size(), vector<bool>(xs.size(), false));
        for(int i=0; i<4*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<ys.size(); ++i) {
            for(int j=0; j<xs.size(); ++j) {
                if(fld[i][j]) {
                    continue;
                }
                fld[i][j] = true;
                res++;
                queue<P> que;
                que.push(make_pair(i, j));
                while(!que.empty()) {
                    P p = que.front(); que.pop();
                    int sy = p.first, sx = p.second;
                    int dy[4] = {0, -1, 0, 1},
                        dx[4] = {1, 0, -1, 0};
                    for(int k=0; k<4; ++k) {
                        int ty = sy + dy[k], tx = sx + dx[k];
                        if(ty < 0 || ys.size() <= ty || tx < 0 || xs.size() <= tx) {
                            continue;
                        }
                        if(fld[ty][tx]) {
                            continue;
                        }
                        que.push(make_pair(ty, tx));
                        fld[ty][tx] = true;
                    }
                }
            }
        }
        cout << res << endl;
    }
}