ARC031 B - 埋め立て
目次
# 問題
https://atcoder.jp/contests/arc031/tasks/arc031_2
# 入力
...
.
- -
x
かo
.
# 出力
すべてのo
が4近傍(上下左右)で繋がっているかどうかを判定する問題です.
ただし、任意の1マスだけx
をo
に変えることが出来ます.
# 解説
がと十分小さいのですべてのx
についてo
に変換してみてo
がすべて繋がるかを試してみることが出来ます.
全マスなのでざっくりと計算量はです.
すべてのマスが繋がっているかの確認には、深さ優先探索を使うことが出来ます.
o
に変えたマスからスタートし、x
に変更し、次の4近傍のうちo
のところに進みます.
そしてx
に変更し、・・・と進めなくなるまで繰り返します.
この深さ優先探索た終了したら、すべてのマスをチェックしてすべてx
に変更されていたらすべてのo
が繋がっていたと判定出来ます.
まだo
が残っていたら繋がっておらず孤立していたということです.
このようにして、 bit全探索のうち1つでもすべてのo
を繋げられるパターンを見つけたらその時点で答えは"YES"
です.
最後まで見つけられなければ"NO"
です.
# 計算量
bit全探索で.
その中の深さ優先探索で.
# 解答
#define MAX_N 10
Int H, W;
vector<bool> C(MAX_N*MAX_N, true);
void input() {
char x;
H = W = 10;
loop(h,0,H) {
loop(w,0,W) {
cin >> x;
if (x == 'x') C[h*W + w] = false;
}
}
}
void dfs(Int x, Int y, Int depth, vector<bool> &c) {
c[y*W+x] = false;
loop(dy,-1,2) {
loop(dx,-1,2) {
if (dy != 0 && dx != 0) continue;
Int x_ = x + dx, y_ = y + dy;
if (x_ < 0 || W <= x_ || y_ < 0 || H <= y_) continue;
if (!c[y_*W + x_]) continue;
dfs(x_, y_, depth+1, c);
}
}
}
bool bit(Int x, Int y, vector<bool> c) {
c[y*W+x] = true;
dfs(x, y, 0, c);
loop(h,0,H) {
loop(w,0,W) {
if (c[h*W+w]) return false;
}
}
return true;
}
void solve() {
loop(h,0,H) {
loop(w,0,W) {
if (bit(w, h, C)) {
cout << "YES" << endl;
return;
}
}
}
cout << "NO" << endl;
}
int main(void) {
input();
solve();
return 0;
}