島の数を数える | アルゴリズム [AOJ 0067][Ruby/Python/c++]


最近アルゴリズム勉強・Python/C++の勉強のためにAizu Online Judge(AOJ)を継続しています。今回は、『島の数を数える』問題です。

0と1で表されたmap上の島の数を数える問題です。

今回は戦略を思いつかずに、かなり試行錯誤をしました。ただ、こういう問題を通して柔軟な発想と、効率的なアルゴリズムのしくみを学んでいきたいと思います!

🤔 Rubyコード

def remove_island(i, j, map)
map[i][j] = '0'
[[0, 1], [1, 0], [0, -1], [-1, 0]].each do |x, y|
next if !(0..11).include?(i + x) || !(0..11).include?(j + y)
if map[i + x][j + y]=='1'
remove_island(i + x, j + y, map)
end
end
end
loop do
map = 12.times.map{ gets.chomp }
count = 0
12.times do |i|
12.times do |j|
if map[i][j] == '1'
count += 1
remove_island(i, j, map)
end
end
end
puts count
break if gets.nil?
end

🐯 Pythonコード

def get_map():
map = []
while True:
try:
tmp = list(raw_input())
if len(tmp) != 12: break
map.append(tmp)
except:
break
return map
def remove_island(x, y, map):
map[x][y] = 0
move = [[1, 0], [0, 1], [-1, 0], [0, -1]]
for i, j in move:
if 0 <= x + i <= 11 and 0 <= y + j <= 11 and map[x + i][y + j] == '1':
map = remove_island(x + i, y + j, map)
return map[:]
while True:
map = get_map()
if len(map) != 12: break
count = 0
for x in range(12):
for y in range(12):
if map[x][y] == '1':
count += 1
map = remove_island(x, y, map)
print count

🍄 c++コード

#include <iostream>
using namespace std;
int m[12][12];
bool valid(int y, int x) {
if(0 <= y && y < 12) {
if(0 <= x && x < 12) {
if(m[y][x] == 1) return true;
}
}
return false;
}
void remove_island(int y, int x) {
int nx, ny;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
m[y][x] = 0;
for(int i = 0; i < 4; i++){
ny = y + dy[i];
nx = x + dx[i];
if(valid(ny, nx)) remove_island(ny, nx);
}
}
int main() {
char c[12];
int ans;
while(1){
for(int i = 0; i < 12; i++) {
if(!(cin >> c)) return 0;
for(int j = 0; j < 12; j++) {
m[i][j] = (int)(c[j] - '0');
}
}
ans = 0;
for(int i = 0; i < 12; i++) {
for(int j = 0; j < 12; j++) {
if(valid(i, j)) {
remove_island(i, j);
ans++;
}
}
}
cout << ans << endl;
}
return 0;
}

🐰 GitHubリポジトリ

当面はAOJを解きながら、アルゴリズムの再勉強をしていくつもりです。Ruby/PythonでのAOJの回答は下のリポジトリに保存しておきます。もしツッコミとかあればぜひ^^

morizyun/aoj-ruby-python - GitHub

🖥 VULTRおすすめ

VULTR」はVPSサーバのサービスです。日本にリージョンがあり、最安は512MBで2.5ドル/月($0.004/時間)で借りることができます。4GBメモリでも月20ドルです。 最近はVULTRのヘビーユーザーになので、「ここ」から会員登録してもらえるとサービス開発が捗ります!

📚 おすすめの書籍