長期投資シミュレーションツール『Tousimu』をリリースしました!

【解答付き】paizaスキルチェック見本問題「島探し (paizaランク S 相当)」を解説!

プログラミング
スポンサーリンク

この記事では

プログラミング学習サービスpaizaラーニング

スキルチェックレベルアップ問題集をわかりやすく解説します!

プログラミング言語はpythonです。

今回はSランク相当の以下の問題を解説します。

他のレベルアップ問題集の解答と解説も紹介しているので

ぜひご参考ください!

またpaizaの各ランクの攻略法は

こちらで詳しく紹介しているので、ぜひご参考ください!

スポンサーリンク

この問題を解くための3つのポイント

まずは「この問題を解くためのポイント」をご説明します。

問題はこちらからご確認ください。

島探し(paizaランクS相当)

この問題を解くためのポイントは以下の3つです。

この問題を解くためのポイント
  • 島を探す
  • 島の大きさを確認
  • 外枠でのエラーを無くす

島を探す

まずは「島を探す」です。

今回の問題では入力された表の中で

"1"が隣接している塊を島としてカウントします。

そのため最初に表のそれぞれの値が"1"なのか判定しなければなりません。

今回は表の左上から右下に進んで調べていくため

列と行に関してfor文を使用します。

''' colが列数、rowが行数 '''

# 各行に対して繰り返す
for i in range(row):
    # 各列に対して繰り返す
    for j in range(col):

for文については、こちらをご参考ください!

次にif文をで表のそれぞれの値が "1" なのかの条件を課します。

"""
map_listは以下のような2次元配列(リスト)
[
    ["0", "1", "1", "0"],
    ["1", "0", "1", "0"],
    ["1", "0", "0", "0"],
    ["0", "0", "1", "1"],
    ["0", "1", "1", "1"]
]
"""

''' colが列数、rowが行数 '''

# 各行に対して繰り返す
for i in range(row):
    # 各列に対して繰り返す
    for j in range(col):
        # "1"の場合
        if map_list[i][j] == "1":

リストとif文については、こちらをご参考ください!

島の大きさを確認

次は「島の大きさを確認」です。

今回の問題は値が "1" の場所ではなく"1"の塊が島なので

"1"なのか判定するだけでは、同じ島を何度もカウントしてしまいます。

そのため以下の流れで島の大きさを確認します!

島の大きさを確認
  1. 各表の値が"1"なのか判定
  2. "1"の場合は"0"に置換
  3. 置換した場所に隣接する上下左右の場所の値も判定
  4. 隣接する上下左右の場所が"0"になるまで2, 3の処理を繰り返す

今回は2, 3, 4の処理を1つの関数にまとめます。

# xが列、yが行
def check(x, y):
    # 2. ~ 4.の処理を書く

次に"1"の場所を記憶するリストを定義し、最初の場所を追加します。

# 関数を定義
def check(x, y):
    # リストを定義し最初の場所を追加
    lands = [[x, y]]
    
    # "0"に置換
    map_list[y][x] = "0"

リストについては、こちらをご参考ください!

そして最初の場所の値を"0"に置換します。

# 関数を定義
def check(x, y):
    # リストを定義し最初の場所を追加
    lands = [[x, y]]
    
    # "0"に置換
    map_list[y][x] = "0"

次に隣接する上下左右の場所の値が"1"なのか判定し

"1"の場合はappendメソッドを使ってリストに追加します。

# 関数を定義
def check(x, y):
    # リストを定義し最初の場所を追加
    lands = [[x, y]]
    
    # "0"に置換
    map_list[y][x] = "0"
    
    # 下の場所
    if map_list[y+1][x] == "1":
        lands.append([x, y+1])
    # 右の場所
    if map_list[y][x+1] == "1":
        lands.append([x+1, y])
    # 上の場所
    if map_list[y-1][x] == "1":
        lands.append([x, y-1])
    # 左の場所
    if map_list[y][x-1] == "1":
        lands.append([x-1, y])

最後にwhile文を使って処理を繰り返します。

while文はリストの要素の座標をpopメソッドを使って

x, y に代入し、リストの要素が無くなるまで繰り返します。

# 関数を定義
def check(x, y):
    # リストを定義し最初の場所を追加
    lands = [[x, y]]

    # landsの要素が無くなるまで繰り返す
    while lands:
        # 座標を更新
        x, y = lands.pop() 
  
        # "0"に置換
        map_list[y][x] = "0"
    
        # 下の場所
        if map_list[y+1][x] == "1":
            lands.append([x, y+1])
        # 右の場所
        if map_list[y][x+1] == "1":
            lands.append([x+1, y])
        # 上の場所
        if map_list[y-1][x] == "1":
            lands.append([x, y-1])
        # 左の場所
        if map_list[y][x-1] == "1":
            lands.append([x-1, y])

while文については、こちらをご参考ください!

外枠でのエラーを無くす

最後は「外枠でのエラーを無くす」です。

実は「島の大きさを確認する」で紹介した関数checkでは

表の一部の場所でエラーが発生してしまいます。

# 関数を定義
def check(x, y):
    # リストを定義し最初の場所を追加
    lands = [[x, y]]

    # landsの要素が無くなるまで繰り返す
    while lands:
        # 座標を更新
        x, y = lands.pop() 
  
        # "0"に置換
        map_list[y][x] = "0"
    
        # 下の場所
        if map_list[y+1][x] == "1":
            lands.append([x, y+1])
        # 右の場所
        if map_list[y][x+1] == "1":
            lands.append([x+1, y])
        # 上の場所
        if map_list[y-1][x] == "1":
            lands.append([x, y-1])
        # 左の場所
        if map_list[y][x-1] == "1":
            lands.append([x-1, y])

それが表の右端や下端などの外枠です。

外枠では隣接する上下左右の場所の中で

データが存在しない部分が含まれてしまいます。

そのため外枠を"0"で囲み、エラーを回避します!

"""
旧)map_list
[
    ["0", "1", "1", "0"],
    ["1", "0", "1", "0"],
    ["1", "0", "0", "0"],
    ["0", "0", "1", "1"],
    ["0", "1", "1", "1"]
]

新)map_list
[
    ["0", "0", "0", "0", "0", "0"],
    ["0", "0", "1", "1", "0", "0"],
    ["0", "0", "1", "1", "0", "0"],
    ["0", "1", "0", "1", "0", "0"],
    ["0", "1", "0", "0", "0", "0"],
    ["0", "0", "0", "1", "1", "0"],
    ["0", "0", "1", "1", "1", "0"],   
    ["0", "0", "0", "0", "0", "0"]
]
"""

"0"で囲むとエラーは回避できますが

行と列がそれぞれ2つずつ増えるので

「島を探す」で紹介したfor文の範囲を変化させなければなりません!

''' colが列数、rowが行数 '''

# 2行目からrow+1行目まで繰り返す
for i in range(1, row+1):
    # 2列目からcol+1列目まで繰り返す
    for j in range(1, col+1):
スポンサーリンク

島探し (paizaランク S 相当)の解答

ではここまで紹介したポイントを使って、問題を解いていきます。

入力を受け取り、表を準備

まずは「入力を受け取り、表を準備」です。

今回の問題では1行目で表の列数と行数が

半角スペース区切りで入力されます。

そのためsplit関数を使って2つの変数に代入し、int型に変換します。

# 表の列数と行数の入力を受け取る
col, row = input().split()

# int型に変換
col = int(col)
row = int(row)

int型などの変数の型については、こちらをご参考ください!

また内包表記を使うと1行で書けるため、よりシンプルです。

# 表の列数と行数の入力を受け取り、int型に変換
col, row = [int(x) for x in input().split()]

内包表記については、こちらをご参考ください!

2行目以降では各行の値が半角スペース区切りで入力されるので

リストを使って2次元配列の要素として代入します。

# 入力を代入するリストを定義
map_list = []

# 各行に対して繰り返す
for i in range(row): 
    # 1行分のリストを追加
    map_list.append(input().split())

さらに「外枠でのエラーを無くす」で紹介したように

エラー回避のため、外枠を"0"で囲みます。

# 1行目を"0"で埋める
map_list = [["0"] * (n+2)] 

# 各行に対して繰り返す
for i in range(row): 
    # "0"で挟む
    map_list.append(["0"] + input().split() + ["0"])

# 1行目と同じリストを最後の行に追加
map_list.append(map_list[0])

入力については、こちらをご参考ください!

島かどうかを判定しその数をカウント

次は「島かどうかを判定しその数をカウント」です。

まずfor文if文を使って表のそれぞれの値が"1"なのか判定します。

''' colが列数、rowが行数 '''

# 2行目からrow+1行目まで繰り返す
for i in range(1, row+1):
    # 2列目からcol+1列目まで繰り返す
    for j in range(1, col+1):
        # "1"の場合
        if map_list[i][j] == "1":

次に島の大きさを確認する関数を定義し

同じ島の場所を全て"0"に置換します。

# 関数を定義
def check(x, y):
    # リストを定義し最初の場所を追加
    lands = [[x, y]]

    # landsの要素が無くなるまで繰り返す
    while lands:
        # 座標を更新
        x, y = lands.pop() 
  
        # "0"に置換
        map_list[y][x] = "0"
    
        # 下の場所
        if map_list[y+1][x] == "1":
            lands.append([x, y+1])
        # 右の場所
        if map_list[y][x+1] == "1":
            lands.append([x+1, y])
        # 上の場所
        if map_list[y-1][x] == "1":
            lands.append([x, y-1])
        # 左の場所
        if map_list[y][x-1] == "1":
            lands.append([x-1, y])

''' colが列数、rowが行数 '''
# 2行目からrow+1行目まで繰り返す
for i in range(1, row+1):
    # 2列目からcol+1列目まで繰り返す
    for j in range(1, col+1):
        # "1"の場合
        if map_list[i][j] == "1":
          # 島の大きさを確認し"0"に置換
      check(j, i)

次に島の数をカウントします。

# 島の数を数える変数
count = 0

''' colが列数、rowが行数 '''
# 2行目からrow+1行目まで繰り返す
for i in range(1, row+1):
    # 2列目からcol+1列目まで繰り返す
    for j in range(1, row+1):
        # "1"の場合
        if map_list[i][j] == "1":
            # 島の大きさを確認し"0"に置換
            check(j, i)

            # 島をカウント
            count += 1

while文については、こちらをご参考ください!

最後にprint関数を使って、結果を出力します。

# 島の数を出力
print(count)

出力については、こちらをご参考ください!

島探し(paizaランクS相当)の解答

まとめると「島探し(paizaランクS相当)」の解答は以下です。

# 表の列数と行数の入力を受け取り、int型に変換
col, row = [int(x) for x in input().split()]

# 1行目を"0"で埋める
map_list = [["0"] * (col+2)] 

# 各行に対して繰り返す
for i in range(row): 
    # "0"で挟む
    map_list.append(["0"] + input().split() + ["0"])

# 1行目と同じリストを最後の行に追加
map_list.append(map_list[0])

# 関数を定義
def check(x, y):
    # リストを定義し最初の場所を追加
    lands = [[x, y]]

    # landsの要素が無くなるまで繰り返す
    while lands:
        # 座標を更新
        x, y = lands.pop() 
  
        # "0"に置換
        map_list[y][x] = "0"
    
        # 下の場所
        if map_list[y+1][x] == "1":
            lands.append([x, y+1])
        # 右の場所
        if map_list[y][x+1] == "1":
            lands.append([x+1, y])
        # 上の場所
        if map_list[y-1][x] == "1":
            lands.append([x, y-1])
        # 左の場所
        if map_list[y][x-1] == "1":
            lands.append([x-1, y])

# 島の数を数える変数
count = 0

''' colが列数、rowが行数 '''
# 2行目からrow+1行目まで繰り返す
for i in range(1, row+1):
    # 2列目からcol+1列目まで繰り返す
    for j in range(1, col+1):
        # "1"の場合
        if map_list[i][j] == "1":
          # 島の大きさを確認し"0"に置換
            check(j, i)

            # 島をカウント
            count += 1

# 島の数を出力
print(count)

ぜひご参考ください!

スポンサーリンク

まとめ

今回はpaizaのスキルチェックレベルアップ問題集の中で

  • 島探し(paizaランクS相当)

の解答と解説を紹介しました。

Sランクの問題になると、まず正しい答えを出力することでさえ難しくなります。

また制限時間がかなり厳しくなってくるので

問題分の読み間違いなどの時間のロスには注意しましょう!

ぜひSランク目指してがんばってください!

また他のレベルアップ問題集の問題についての解説も、ぜひご参考ください!

Pythonを学びたいと思っているけど

  • プログラミングスクールに数十万円も払えない・・・
  • 独学だとどうやって学んだらいいかわからない・・・
  • Pythonのインストールや環境構築がよくわからない・・・

といったお悩みを抱えている方はいませんか?

Pythonの学習はオンライン学習サービスのPyQがおすすめです!

PyQ

PyQの特徴は圧倒的なコストパフォーマンスで

たった月額3,040円で以下のPythonに関する内容が学び放題です!

PyQで学べる内容
  • プログラミングの基本
  • Python入門〜中級
  • ユニットテスト、設計
  • Webアプリ開発
  • Django(Pythonを使ったWebアプリ開発のフレームワーク)
  • スクレイピング
  • データ解析
  • 機械学習
  • 統計入門
  • アルゴリズム

またブラウザ上でコードを書いて学習できるため

面倒なPythonのインストールや環境構築なども一切不要です!

実際に私もプログラミングを始めた頃に利用していて

PyQを一通りやり終えた後は

  • Djangoを使ったポートフォリオの制作
  • スクレイピングによる作業の自動化
  • ディープラーニング

などのプログラムを自分で書けるようになり

paizaのスキルチェックでもSランクを所得しました!

PyQは登録後すぐに学習を開始できるので

Pythonの学習方法でお悩みの方は、今すぐPyQで学習をスタートしましょう!

しかし

  • 独学で挫折した経験がある・・・
  • 短期間でpythonを習得したい!
  • プロのエンジニアからpythonを学びたい!

という方は、PyQでの独学よりも

プログラミングスクールでの学習が最適かもしれません!

pythonが学べるおすすめのプログラミングスクールはこちら!

TechAcademy Pythonコース

おすすめスクールNo.1:TechAcademy Pythonコース

TechAcademyがおすすめな理由
  • 学習システムを1週間無料で体験できる!
  • 完全オンラインだから、忙しくても続けられる!
  • 各受講生に現役エンジニアのメンターがつく!

DIVE INTO CODE エキスパートAIコース

おすすめスクールNo.2:DIVE INTO CODE エキスパートAIコース

DIVE INTO CODEがおすすめな理由
  • 本気の人のためのスクール!事前テストで選考あり!
  • 無料説明会&体験セミナーあり!
  • 通学 or オンラインが選択できる!

CodeCamp Pythonデータサイエンスコース

おすすめスクールNo.3:CodeCamp Pythonデータサイエンスコース

DIVE INTO CODEがおすすめな理由
  • 無料体験レッスン受講で10,000円引き
  • 受講者数30,000人超えの圧倒的な実績!
  • レッスン満足度96.6%

ぜひ自分に合った学習方法でPythonを習得しましょう!

プログラミング paizaでSランク!
スポンサーリンク
Follow Me!
スポンサーリンク
まろぶろぐ
タイトルとURLをコピーしました