考えて競プロする

プログラミングコンテストの問題をどう考えて解いたかを記録していくブログです。使用言語はPython3

ABC004-B - 回転 を解く

ABC004-B - 回転

  

4×4の文字列を180度回転させて出力する問題

 

自分で考えてやる分には簡単だけど

プログラムでやるとなると少し厄介そうだ

2次元配列を使うのがいいかな

 

その前に、180度回転させると各座標はどこに移動するのか

はっきりさせる必要がある

 

(脳内シミュレーション中…)

 

座標(1,1)は座標(4,4)に移動

座標(1,2)は座標(4,3)に移動

座標(2,1)は座標(3,4)に移動

座標(3,2)は座標(2,3)に移動

 

なんか移動前と移動後の座標を足すと (5,5) になるっぽいな

とりあえずこの法則に従って移動後の座標を決めてみるか 

 

提出したコード

# 回転前
l1=[]
# 回転後(4×4、''で初期化
l2=[['','','',''] for i in range(4)]

# 入力(4行)
for x in range(4):
  l1.append(list(map(str,input().split())))

# 回転
for i1 in range(4):
  for j1 in range(4):
    i2=3-i1
    j2=3-j1
    l2[i2][j2]=l1[i1][j1]

# 出力
for x in l2:
  print(' '.join(x))
 

結構いろんなことを新しくやっているので説明する

まずはこれ

# 回転後(4×4、''で初期化
l2=[['','','',''] for i in range(4)]
これは['', '', '', '']の4列のリストを4つ作成してそれをさらにリストに入れている
外側を [ ] で囲うことでリストの入れ子が作れるわけだ

 

これにより2次元配列を再現することができた

 

続いてこちら

# 入力(4行)
for x in range(4):
  l1.append(list(map(str,input().split()))) 

list(map(str,input().split())) は半角スペース区切りの値をstr型で

リストに1字ずつ詰めていく書き方

 

これをリストの l1 に1行ずつ詰めていくことで

入力値を二次元配列に入れることができた

 

次は肝心の処理部

# 回転
for i1 in range(4):
  for j1 in range(4):
    i2=3-i1
    j2=3-j1
    l2[i2][j2]=l1[i1][j1]
処理前の座標を(i1,j1)、処理後の座標を(i2,j2) としている
 
冒頭の考察で、座標を足し合わせると(5,5) になると言ったが、
リストは 0-index(0から始まる) であるため
(0,0) → (3,3) のように回転によって座標が移動する
したがって 0-index の場合は移動前と移動後の座標を足し合わせると (3,3) になる
 

以上より、3から移動前の座標を引くことで、移動後の座標を求めている 

 

最後に、半角スペースで列を結合して結果を出力する

# 出力
for x in l2:
  print(' '.join(x))
 
提出結果はAC
 
解説を読んでみたところ、配列を逆からコピーすることで回転処理を行っていた
確かにそちらの方が汎用性高いな〜
気になる方は解説も読んでみてください