日別アーカイブ: 2022年10月31日

PaizaAランクLvアップ問題と解説その2(Ruby)マップの判定(横・縦)

1から続いています

※スキルチェック問題ではありません。

規約により公式の解答コードそのままはよろしくないので、
オリジナルのコードにしています。

詳しくはコチラ

なるべくわかりやすい解説を付けました。

問題3:マップの判定・横 (paizaランク C 相当)

行数 H , 列数 W の盤面があり、盤面の各マスには文字が 1 つだけ書かれています。
盤面が与えられるので、「左右のマスが “#” 」であるようなマスの座標を全て出力してください。

ただし、左端のマスの場合は「右のマスが “#” 」であれば、右端のマスの場合は「左のマスが “#” 」であれば条件を満たすものとします。

なお、マスの座標系は左上端のマスの座標を ( y , x ) = ( 0 , 0 ) とし、
下方向が y 座標の正の向き、右方向が x 座標の正の向きとします。

入力される値
H W     
S_0     
...     
S_(H-1)

・ 1 行目には盤面の行数を表す整数 H , 盤面の列数を表す整数 W が与えられます。
・ 続く H 行のうち i 行目 (0 ≦ i < H) には、盤面の i 行目の文字をまとめた文字列 S_i が与えられ、 S_i の j 文字目は、盤面の i 行目の j 列目に書かれている文字を表します。(0 ≦ j < W)

期待する出力
N (1 ≦ N ≦ H×W) 行の出力

・ 条件を満たすマスの y , x 座標を出力してください。
・ 左上 (y = 0, x = 0) のマスから順に、x 座標 , y 座標の順で増加するように出力してください。詳しくは入出力例を参考にしてください。

y_1 x_1
...
y_N x_N

 

条件
すべてのテストケースにおいて、以下の条件をみたします。

・ 1 ≦ H, W ≦ 20
・ S は W 文字の文字列
・ S の各文字は "." または "#"
・ 条件を満たすマスが少なくとも 1 つ以上存在します

 

入力例1
3 3
#.#
.#.
...
出力例1
0 1
1 0
1 2
入力例2
4 4
####
####
####
####
出力例2
0 0
0 1
0 2
0 3
1 0
1 1
1 2
1 3
2 0
2 1
2 2
2 3
3 0
3 1
3 2
3 3

何が問われているか?(問題の抽象化)

座標系問題のx軸の判定

解答 ※ifと||で3パターンに対応している

#1行目の半角スペース刻みの入力値を変数に多重代入する
h, w = gets.split.map(&:to_i)

#盤面の情報を配列として代入していく
chart = h.times.map { gets.chomp.chars }

chart.each.with_index do |yoko, line|
  yoko.each_index do |index|

# 左端にいるかどうか(x == 0)または左に#があるかどうか確認することで右端(yoko[x - 1])も対応している
  if index == 0 || yoko[index - 1] == '#'

# 右端(x == w - 1)にいるかどうかまたは右に#があるかどうか(yoko[x + 1] == '#')確認している
# 以上により左右に#があるかがわかる
  if index == w - 1 || yoko[index + 1] == '#'

#条件を満たしたy軸とx軸を半角スペース刻みで出力する
    puts line.to_s + ' ' + index.to_s 
  end
  end
  end
end

問題4: マップの判定・縦 (paizaランク C 相当)

マップの行数 H と列数 W とマップを表す H 行 W 列の文字列 S_1 … S_H が与えられるので、
上下のマスがどちらも ‘#’ であるようなマスの y , x 座標 を答えてください。

ただし、上端のマスの場合は「下のマスが ‘#’」であれば、下端のマスの場合は「上のマスが ‘#’」であれば条件を満たすものとします。

なお、マスの座標系は左上端のマスの座標を ( y , x ) = ( 0 , 0 ) とし、
下方向が y 座標の正の向き、右方向が x 座標の正の向きとします。

入力される値
H W     
S_0     
...     
S_(H-1)

・ 1 行目には盤面の行数を表す整数 H , 盤面の列数を表す整数 W が与えられます。
・ 続く H 行のうち i 行目 (0 ≦ i < H) には、盤面の i 行目の文字をまとめた文字列 S_i が与えられ、 S_i の j 文字目は、盤面の i 行目の j 列目に書かれている文字を表します。(0 ≦ j < W)

期待する出力
N (1 ≦ N ≦ H×W) 行の出力

・ 条件を満たすマスの y , x 座標を出力してください。
・ 左上 (y = 0, x = 0) のマスから順に、x 座標 , y 座標の順で増加するように出力してください。詳しくは入出力例を参考にしてください。

y_1 x_1
...
y_N x_N
条件
すべてのテストケースにおいて、以下の条件をみたします。

・ 1 ≦ H, W ≦ 20
・ S は W 文字の文字列
・ S の各文字は '.' または '#'
・ 条件を満たすマスが少なくとも 1 つ以上存在します
入力例1
3 3
###
...
###
出力例1
1 0
1 1
1 2
入力例2
4 4
#.#.
.#.#
.#.#
#.#.
出力例2
0 1
0 3
3 1
3 3

何が問われているか?(問題の抽象化)

座標系問題のy軸の判定

解答と解説

#1行目の半角スペース刻みの入力値を変数に多重代入する
h, w = gets.split.map(&:to_i)

#盤面の情報を配列として代入していく
chart = h.times.map { gets.chomp.chars }
chart.each.with_index do |yoko, line|
  yoko.each_index do |index|

# 上端(line == 0)にいるかまたは上(a[line - 1 ][index] == '#')に#があるかどうか確認することで下端も対応している
  if line == 0 || a[line - 1 ][index] == '#' 

# 下端(line == h - 1)にいるかまたは下(a[line + 1 ][index] == '#')に#があるかどうか確認している 
  if line == h - 1 || a[line + 1 ][index] == '#'

#条件を満たしたy軸とx軸を半角スペース刻みで出力する
     puts line.to_s + ' ' + index.to_s 
  end
  end
  end
end

※配列は0から始まるので下端が(line == h – 1)となっています・

問題5:マップの判定・縦横 (paizaランク B 相当)

マップの行数 H と列数 W とマップを表す H 行 W 列の文字列 S_1 … S_H が与えられるので、
隣接する上下左右のマスが全て ‘#’ であるマスの y , x 座標 を答えてください。

ただし、左端のマスの場合は「右のマスが ‘#’ 」であれば、右端のマスの場合は「左のマスが ‘#’ 」であれば隣接する左右のマスが全て ‘#’ であるものとします。
また、上端のマスの場合は「下のマスが ‘#’ 」であれば、下端のマスの場合は「上のマスが ‘#’ 」であれば隣接する上下のマスが全て “#” であるものとします。

なお、マスの座標系は左上端のマスの座標を ( y , x ) = ( 0 , 0 ) とし、
下方向が y 座標の正の向き、右方向が x 座標の正の向きとします。

入力される値
H W     
S_0     
...     
S_(H-1)

・ 1 行目には盤面の行数を表す整数 H , 盤面の列数を表す整数 W が与えられます。
・ 続く H 行のうち i 行目 (0 ≦ i < H) には、盤面の i 行目の文字をまとめた文字列 S_i が与えられ、 S_i の j 文字目は、盤面の i 行目の j 列目に書かれている文字を表します。(0 ≦ j < W)

期待する出力
N (1 ≦ N ≦ H×W) 行の出力

・ 条件を満たすマスの y , x 座標を出力してください。
・ 左上 (y = 0, x = 0) のマスから順に、x 座標 , y 座標の順で増加するように出力してください。詳しくは入出力例を参考にしてください。

y_1 x_1
...
y_N x_N
条件
すべてのテストケースにおいて、以下の条件をみたします。

・ 1 ≦ H, W ≦ 20
・ S は W 文字の文字列
・ S の各文字は '.' または '#'
・ 条件を満たすマスが少なくとも 1 つ以上存在します

入力例1

3 3
##.
###
...

出力例1

0 0
0 2

入力例2

10 10
##########
..........
##########
##########
..........
#.#.#.#.#.
.#.#.#.#.#
#.#.#.#.#.
.#.#.#.#.#
..........

出力例2

6 0
6 2
6 4
6 6
6 8
7 1
7 3
7 5
7 7
7 9

何が問われているか?(問題の抽象化)

座標系問題のx軸とy軸の判定

解答と解説

#1行目の半角スペース刻みの入力値を変数に多重代入する
h, w = gets.split.map(&:to_i)

#盤面の情報を配列として代入していく
chart = h.times.map { gets.chomp.chars }


chart.each.with_index do |yoko, line|
  yoko.each_index do |index|

# 左端にいるかどうかまたは左に#があるかどうか確認することで右端も対応している   
if index == 0 || yoko[index - 1] == '#' 

# 右端にいるかどうかまたは右に#があるかどうか確認することで左端も対応している  
  if index == w - 1 || yoko[index + 1] == '#'

# 上端にいるかまたは上に#があるかどうか確認することで下端も対応している
    if line == 0 || a[line - 1 ][index] == '#'

# 下端にいるかまたは下に#があるかどうか確認している
      if line == h - 1 || a[line + 1 ][index] == '#'
        puts line.to_s + ' ' + index.to_s
      end
    end
  end
end
end
end

その3に続きます