▼問題
▼考え方
この問題を解くために私が考えた内容1~7を以下に示します。
-
へびの移動は最大100回なので、100回ループを回します。
-
以下の3つの引数を関数caldistanceに渡して、y,x方向の移動距離を計算します。移動距離の情報を返します。関数に渡す引数は、①現在の時刻を示す変数i、②現在向いている方角を示す変数nesw、③方向転換する時刻と転換する向きを格納したリストtd 1行ずつ、です。
-
現在の座標(y,x)と2の戻り値(y,x方向の移動距離)を関数nextpositionに渡して、移動が可能かどうかの判定を行います。移動が不可能ならば"stop"を返します。移動が可能ならば"ok"を返します。さらに、次の座標を返します。考え方3の詳細は、以下に示します。
-
y軸方向において、スタート位置を含む移動の際に通ったマップのマスを'*'に変更します。
-
x軸方向において、スタート位置を含む移動の際に通ったマップのマスを'*'に変更します。
-
移動後の座標を現在の座標に設定します。
-
方向転換した場合は向いている方角を更新します。
[考え方3の詳細]
3.1
y軸方向の移動(dyx[1] == 0)か、x軸方向の移動(dyx[0] == 0)かで処理を分けます。
3.2
y軸方向の移動の処理をするために、2次元リストSから列を抽出しリストS_rに格納します。
3.3
y軸の負の方向(dyx[0] < 0)に移動するのか、正の方向に移動するのかで、処理を分けます。
3.4
y軸の負の方向に移動することを考えます。移動(y+dyx[0]からy、あるいは、0からy)に際して、障害物("#")があるか、自分の身体("*")があるか、マップ外かどうかを判定します。(移動に際し、障害物や自分の身体がある場合は)関数calforwordindexを用いてその位置を計算します。
▼コード
############### 関数処理 ###############
# caldistance: y,x座標の移動距離を計算を計算する関数
def caldistance(i,nesw,td_j):
# dy: y座標の移動距離を示す変数
dy = 0
# dx: x座標の移動距離を示す変数
dx = 0
td_j[0] = int(td_j[0])
if i != td_j[0]:
if nesw == 0:
dy -= 1
elif nesw == 1:
dx += 1
elif nesw == 2:
dy += 1
else:
dx -= 1
else:
if td_j[1] == "L":
if nesw == 0:
dx -= 1
elif nesw == 1:
dy -= 1
elif nesw == 2:
dx += 1
else:
dy += 1
else:
if nesw == 0:
dx += 1
elif nesw == 1:
dy += 1
elif nesw == 2:
dx -= 1
else:
dy -= 1
return [dy,dx]
# calforwordindex: 障害物や自分の身体の位置を計算する関数
def calforwordindex(S_r_sub,mark):
return [l for l in range(len(S_r_sub)-1,-1,-1) if S_r_sub[l] == mark]
# nextposition: 移動が可能かどうかを判定と、次の座標を返す関数
def nextposition(y,x,dyx):
# 考え方3.1.
if dyx[1] == 0:
# 考え方3.2.
# S_r: 2次元リストSから列を抽出し格納するリスト
S_r = [r[x] for r in S]
# 考え方3.3.
if dyx[0] < 0:
# 考え方3.4.
# S_r_sub: 移動予定の部分を抽出し格納するリスト
S_r_sub = S_r[max(y+dyx[0],0):y]
if "#" in S_r_sub:
index = calforwordindex(S_r_sub,"#")
return ["stop",y-(len(S_r_sub)-(index[0]+1)),x]
if "*" in S_r_sub:
index = calforwordindex(S_r_sub,"*")
return ["stop",y-(len(S_r_sub)-(index[0]+1)),x]
if ("#" not in S_r_sub) and ("*" not in S_r_sub) and (y+dyx[0] <= -1):
return ["stop",max(0,y+dyx[0]),x]
else:
S_r_sub = S_r[y+1:min(y+dyx[0]+1,H-1)]
if "#" in S_r_sub:
index = calforwordindex(S_r_sub,"#")
return ["stop",y+index[0]-1,x]
if "*" in S_r_sub:
index = calforwordindex(S_r_sub,"*")
return ["stop",y+index[0]-1,x]
if ("#" not in S_r_sub) and ("*" not in S_r_sub) and (y+dyx[0] >= H):
return ["stop",min(y+dyx[0],H-1),x]
return ["ok",y+dyx[0],x]
else:
if dyx[1] < 0:
S_r_sub = S[y][max(x+dyx[1],0):x]
if "#" in S_r_sub:
index = calforwordindex(S_r_sub,"#")
return ["stop",y,x-(len(S_r_sub)-(index[0]+1))]
if "*" in S_r_sub:
index = calforwordindex(S_r_sub,"*")
return ["stop",y,x-(len(S_r_sub)-(index[0]+1))]
if ("#" not in S_r_sub) and ("*" not in S_r_sub) and (x+dyx[1] <= -1):
return ["stop",y,max(0,x+dyx[1])]
else:
S_r_sub = S[y][x+1:min(x+dyx[1]+1,W-1)]
if "#" in S_r_sub:
index = calforwordindex(S_r_sub,"#")
return ["stop",y,x+index[0]-1]
if "*" in S_r_sub:
index = calforwordindex(S_r_sub,"*")
return ["stop",y,x+index[0]-1]
if ("#" not in S_r_sub) and ("*" not in S_r_sub) and (x+dyx[1] >= W):
return ["stop",y,min(x+dyx[1],W-1)]
return ["ok",y,x+dyx[1]]
############### メイン関数処理 ###############
H,W,sy,sx,N = map(int,input().split())
S = [list(input()) for _ in range(H)]
# td: 方向転換する時刻と転換する向きを格納したリスト
td = [list(input().split()) for _ in range(N)]
# nesw: 現在向いている方角を示す変数 0:北,1:東,2:南,3:西
nesw = 0
# y: 現在のy座標を示す変数
y = sy
# x: 現在のx座標を示す変数
x = sx
# j: リストtdを1行ずつ操作するための変数
j = 0
# 考え方1.
for i in range(100):
# 考え方2.
# dyx: y,x座標の移動距離に関する情報を格納するリスト
dyx = caldistance(i,nesw,td[j])
# 考え方3.
# checkresult: 移動が可能かどうかの判定結果の文字列を格納する変数
# ny: 次のy座標を示す変数
# nx: 次のx座標を示す変数
checkresult,ny,nx = nextposition(y,x,dyx)
# 考え方4.
if y < ny:
y1 = y
y2 = ny+1
elif y > ny:
y1 = ny
y2 = y+1
else:
y1 = 0
y2 = 0
for k in range(y1,y2):
S[k][x] = "*"
# 考え方5.
if x < nx:
x1 = x
x2 = nx+1
elif x > nx:
x1 = nx
x2 = x+1
else:
x1 = 0
x2 = 0
for k in range(x1,x2):
S[y][k] = "*"
if checkresult != "ok":
break
else:
# 考え方6.
y = ny
x = nx
# 考え方7.
if i == int(td[j][0]):
if td[j][1] == "L":
nesw -= 1
else:
nesw += 1
if nesw > 3:
nesw = 0
elif nesw < 0:
nesw = 3
if j < len(td)-1:
j += 1
for i in range(H):
print(*S[i],sep='')