[AOJ] 1130 Red and Black

 · 1 min read

AOJの1130、Red and Blackをc++で解きました。

よくあるグリッド系の問題ですが、初めてこれ系の解きました。
これでfor文でゴリ押し出来ない問題が解けるようになりました。

今回は練習がてらに
幅優先探索・深さ優先探索どちらでも解いてみました。
DPでも解けるそうですが、イマイチDPは書き方が分かりません。。。

問題文はこちら

コード(幅優先)

// 横型探索
#include <iostream>
#include <string>
#include <vector>
#include <queue>
using namespace std;
int w, h;
int mx[] = {0, 0, -1, 1};
int my[] = {-1, 1, 0, 0};
int main() {
while ( true ) {
int x, y, cnt = 0;
cin >> w >> h;
if ( w == 0 && h == 0 ) break;
vector<string> v(h);
queue<int> s;
for ( int i = 0; i < h; i++ ) {
cin >> v[i];
// @の座標を記録
for ( int j = 0; j < v[i].size(); j++ ) {
if ( v[i][j] == '@' ) {
y = i;
x = j;
}
}
}
// キューにスタート地点を追加
s.push(x);
s.push(y);
while(!s.empty()) {
x = s.front(); s.pop();
y = s.front(); s.pop();
for ( int i = 0; i < 4; i++ ) {
int nx = x + mx[i], ny = y + my[i];
if ( 0 <= nx && nx < w && 0 <= ny && ny < h && v[ny][nx] == '.' ) {
v[ny][nx] = '#';
s.push(nx);
s.push(ny);
}
}
cnt++;
}
cout << cnt << endl;
}
return 0;
}

コード(深さ優先)

// 縦型探索
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int w, h;
int mx[] = {0, 0, -1, 1};
int my[] = {-1, 1, 0, 0};
int dfs(int x, int y, vector<string> &v) {
int cnt = 1;
for ( int i = 0; i < 4; i++ ) {
int nx = x + mx[i], ny = y + my[i];
if ( 0 <= nx && nx < w && 0 <= ny && ny < h && v[ny][nx] == '.' ) {
v[ny][nx] = '#';
cnt += dfs(nx, ny, v);
}
}
return cnt;
}
int main() {
while ( true ) {
int x, y;
cin >> w >> h;
if ( w == 0 && h == 0 ) break;
vector<string> v(h);
for ( int i = 0; i < h; i++ ) {
cin >> v[i];
for ( int j = 0; j < v[i].size(); j++ ) {
if ( v[i][j] == '@' ) {
y = i;
x = j;
}
}
}
cout << dfs(x, y, v) << endl;
}
return 0;
}
AOJC++
© 2012-2025 Leko