[伯俊13913]-鬼ごっこ(4)
2720 ワード
💡質問する
https://www.acmicpc.net/problem/13913
💡に答える
既存のかくれんぼでは,逆追跡の問題のみが増加した.
bfsではかなり簡単であるが,2つの方法で解いた.
1つは優先キューデータ構造を用いたBFSである.
もう1つはキューデータ構造+BFS+再帰である.
答え方は以下の通りです.
優先キュー+BFSの使用
1.heapqに保存:(時間、現在位置、[今まで行った場所])
2.pop値が示す現在位置が目標点と同じかどうかを比較し続け、bfsを実行する.
キュー+BFS+再帰
1.bfsですが、dpを2次元配列として作成し、前回アクセスした場所を保存します.
2.同様にbfsを実行します.
3.現在位置が目標点と同じ場合は、再帰的に逆トレースを実行します.
💡コード#コード#
1番コード
import heapq
def bfs(now, target):
if now == target:
return 0, [now]
elif now > target:
return now - target, [i for i in range(now, target - 1, -1)]
else:
heapq.heappush(q, [0, now, [now]])
while q:
cnt, pos, trace = heapq.heappop(q)
for i in [pos * 2, pos - 1, pos + 1]:
if i == target:
return cnt + 1, trace + [i]
if 0 <= i <= 100000 and not dp[i]:
dp[i] = True
heapq.heappush(q, [cnt + 1, i, trace + [i]])
if __name__ == "__main__":
N, K = map(int,input().split())
dp = [False] * (100000 + 1)
q = []
res, trace = bfs(N, K)
print(res)
print(*trace)
2番コードfrom collections import deque
import sys
def check(now, target, res):
if now == target:
return res[::-1]
else:
res.append(dp[target][1])
return check(now, dp[target][1], res)
def bfs(now, target):
if now == target:
return 0, [now]
elif now > target:
return now - target, [i for i in range(now, target - 1, -1)]
else:
dp[now][0] = 0
while q:
pos = q.popleft()
for i in [pos * 2, pos + 1, pos -1]:
if dp[target][0] != -1:
return dp[target][0], check(now, target, [target])
break
if 0 <= i <= 100000 and dp[i][0] == -1:
dp[i][0] = dp[pos][0] + 1
dp[i][1] = pos
q.append(i)
if __name__ == "__main__":
sys.setrecursionlimit(10000)
N, K = map(int, input().split())
dp = [[-1,-1] for _ in range(100001)]
q = deque()
q.append(N)
res1, res2 = bfs(N, K)
print(res1)
print(*res2)
結果
結論として,第2の方法は時間的複雑さの面でより有効である.
個人的にも満足のいく質問です.
結果は以下の通りです.
1号メソッド結果
2号メソッド結果
Reference
この問題について([伯俊13913]-鬼ごっこ(4)), 我々は、より多くの情報をここで見つけました https://velog.io/@jengyoung/백준-13913-숨바꼭질4テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol