[白俊]7576&7569トマト🍅
38986 ワード
[白俊]https://www.acmicpc.net/problem/7576トマト(2次元)
[白俊]https://www.acmicpc.net/problem/7569トマト(三次元)
2 Dトマトと3 Dトマトの問題を解いてみます.
2次元トマトと3次元トマトはほぼ似たような問題ですが、よく知らないbfsアルゴリズムと3次元配列を一緒に処理するので、頭の中でうまく描けないので、もっと複雑な感じがします.
比較的容易な二次元トマト問題をもとに,解法を整理した.
2 Dトマト
[白俊]https://www.acmicpc.net/problem/7569トマト(三次元)
2 Dトマトと3 Dトマトの問題を解いてみます.
2次元トマトと3次元トマトはほぼ似たような問題ですが、よく知らないbfsアルゴリズムと3次元配列を一緒に処理するので、頭の中でうまく描けないので、もっと複雑な感じがします.
比較的容易な二次元トマト問題をもとに,解法を整理した.
2 Dトマト
input
for i in range(N):
tmp = list(sys.stdin.readline().split())
for j in range(M):
if '-1' == tmp[j]:
visited[i][j] = -1
elif '1' == tmp[j]:
que.append([i, j])
visited[i][j] = 1
box.append(tmp)
Input段階でやるべきこと
処理トマトがある場所を訪問します。
queにトマトが入っている位置。
トマトがない位置-1を処分します。
=>後でトマトがあったのにアクセスできなかったので0しか残っていなかったのですが、
BFS
def bfs():
global m # 최댓값을 저장
while len(que) != 0:
y, x = que.popleft() # 넣어두었던 좌표 y, x
for i in range(4): # 4방향 탐색할 좌표 설정
nx = x + dx[i]
ny = y + dy[i]
if 0 <= ny < N and 0 <= nx < M: # 탐색할 좌표가 범위 안에 있나??
if visited[ny][nx] == 0 and box[ny][nx] == '0': # 방문한 적이 없고 익지 않은 토마토가 있는가?
box[ny][nx] = 1 # 토마토를 익힘
visited[ny][nx] = visited[y][x] + 1 # 익히는 데 걸린 날짜 저장
m = m if m > visited[ny][nx] else visited[ny][nx]
que.append([ny, nx]) #익힌 토마토 좌표를 큐에 저장
for n in range(N): # 하나라도 0이 남았다면 -1 리턴
if 0 in visited[n]:
return -1
else:
return m-1
deque
Pythonでキューを使用する場合,listのpop(0)を使用すると,原理的にリストの最後のインデックスから順次アクセスするため,時間的複雑度はO(N)である.本題では,O(1)に減らすために集合ライブラリを導入し,queリストをdequeとする.
熟知した日付は、アクセスリストの対応する座標に格納されます。
どの座標の中で最後のトマトが熟すか分からないので、最低価格を格納するために変数mを別途作りました。
スタート地点のトマトは既にアクセスリストに1が保存されています。
(熟れていますが、処理には1日かかるようです)
(処理しないと、熟していないトマトを区別するのが難しい)
最後にm-1対価をします。
BFS問題ではアクセスとどこでアクセス処理を行うかが重要!
この問題については,queに登録する前に必ず処理しなければならない.
複数のトマトがある場合は、queを入れる順番でトマトの方向ごとに交互に行い、アクセス処理を行う前にqueを入れると、複数の方向から近い座標が同時に1つのトマトに近づくので頭が痛くなります。これで白俊はタイムアウトに処理されます。
完全なコード
# [백준] https://www.acmicpc.net/problem/7576 토마토(2차원)
# BFS '최소 날짜'
import sys
import collections
sys.stdin = open('basic/BOJ7576.txt')
M, N = list(map(int, sys.stdin.readline().split()))
box = []
que = collections.deque([])
visited = [[0] * M for _ in range(N)]
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
day = 0
m =0 # 최댓값을 저장하는 변수
idx = []
for i in range(N):
tmp = list(sys.stdin.readline().split())
for j in range(M):
if '-1' == tmp[j]:
visited[i][j] = -1
elif '1' == tmp[j]:
que.append([i, j]) # 토마토의 위치를 미리 que에 넣고 시작
visited[i][j] = 1
box.append(tmp)
def bfs():
global m
while len(que) != 0:
y, x = que.popleft()
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if 0 <= ny < N and 0 <= nx < M:
if visited[ny][nx] == 0 and box[ny][nx] == '0':
box[ny][nx] = 1
visited[ny][nx] = visited[y][x] + 1
m = m if m > visited[ny][nx] else visited[ny][nx]
que.append([ny, nx])
for n in range(N):
if 0 in visited[n]:
return -1
else:
return m-1
for n in range(N):
if '0' in box[n]:
print(bfs())
exit(0)
else:
print(0)
3 Dトマト
3次元トマト問題は2次元で高さだけを増やす方向とfor文でif文を増やすと似た方向に戻ります.for k in range(H):
temp =[]
for i in range(N):
tmp = list(sys.stdin.readline().split())
for j in range(M):
if '-1' == tmp[j]:
visited[k][i][j] = -1
elif '1' == tmp[j]:
que.append([k, i, j])
visited[k][i][j] = 1
temp.append(tmp)
box.append(temp)
input
3 Dリストを受信する過程で、1 Dリストをtmpリストに保存し、tmpを2 D tempリストに再保存するトラブルに遭遇しました。
tempリストをボックスに再保存することで解決しました。
△これよりもっといい方法があるようだが、まだ方法が見つからない。
# [백준] https://www.acmicpc.net/problem/7569 토마토(3차원)
# BFS '최소 날짜'
import sys
import collections
sys.stdin = open('test/04.txt')
M, N, H = list(map(int, sys.stdin.readline().split()))
box = []
que = collections.deque([])
visited = [[[0] * M for _ in range(N)] for _ in range(H)]
dx = [0, 0, -1, 1, 0, 0]
dy = [0, 0, 0, 0, -1, 1]
dh = [-1, 1, 0, 0, 0, 0]
m = 0
for k in range(H):
temp =[]
for i in range(N):
tmp = list(sys.stdin.readline().split())
for j in range(M):
if '-1' == tmp[j]:
visited[k][i][j] = -1
elif '1' == tmp[j]:
que.append([k, i, j])
visited[k][i][j] = 1
temp.append(tmp)
box.append(temp)
def bfs():
global m
while len(que) != 0:
h, y, x = que.popleft()
for i in range(6):
nh = h + dh[i]
nx = x + dx[i]
ny = y + dy[i]
if 0 <= ny < N and 0 <= nx < M and 0 <= nh < H:
if visited[nh][ny][nx] == 0 and box[nh][ny][nx] == '0':
box[nh][ny][nx] = 1
visited[nh][ny][nx] = visited[h][y][x] + 1
m = m if m > visited[nh][ny][nx] else visited[nh][ny][nx]
que.append([nh, ny, nx])
for h in range(H):
for n in range(N):
if 0 in visited[h][n]:
return -1
else:
return m-1
for h in range(H):
for n in range(N):
if '0' in box[h][n]:
print(bfs())
exit(0)
else:
print(0)
Reference
この問題について([白俊]7576&7569トマト🍅), 我々は、より多くの情報をここで見つけました
https://velog.io/@crystalhwang16/백준-75767569-토마토
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
for i in range(N):
tmp = list(sys.stdin.readline().split())
for j in range(M):
if '-1' == tmp[j]:
visited[i][j] = -1
elif '1' == tmp[j]:
que.append([i, j])
visited[i][j] = 1
box.append(tmp)
def bfs():
global m # 최댓값을 저장
while len(que) != 0:
y, x = que.popleft() # 넣어두었던 좌표 y, x
for i in range(4): # 4방향 탐색할 좌표 설정
nx = x + dx[i]
ny = y + dy[i]
if 0 <= ny < N and 0 <= nx < M: # 탐색할 좌표가 범위 안에 있나??
if visited[ny][nx] == 0 and box[ny][nx] == '0': # 방문한 적이 없고 익지 않은 토마토가 있는가?
box[ny][nx] = 1 # 토마토를 익힘
visited[ny][nx] = visited[y][x] + 1 # 익히는 데 걸린 날짜 저장
m = m if m > visited[ny][nx] else visited[ny][nx]
que.append([ny, nx]) #익힌 토마토 좌표를 큐에 저장
for n in range(N): # 하나라도 0이 남았다면 -1 리턴
if 0 in visited[n]:
return -1
else:
return m-1
# [백준] https://www.acmicpc.net/problem/7576 토마토(2차원)
# BFS '최소 날짜'
import sys
import collections
sys.stdin = open('basic/BOJ7576.txt')
M, N = list(map(int, sys.stdin.readline().split()))
box = []
que = collections.deque([])
visited = [[0] * M for _ in range(N)]
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
day = 0
m =0 # 최댓값을 저장하는 변수
idx = []
for i in range(N):
tmp = list(sys.stdin.readline().split())
for j in range(M):
if '-1' == tmp[j]:
visited[i][j] = -1
elif '1' == tmp[j]:
que.append([i, j]) # 토마토의 위치를 미리 que에 넣고 시작
visited[i][j] = 1
box.append(tmp)
def bfs():
global m
while len(que) != 0:
y, x = que.popleft()
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if 0 <= ny < N and 0 <= nx < M:
if visited[ny][nx] == 0 and box[ny][nx] == '0':
box[ny][nx] = 1
visited[ny][nx] = visited[y][x] + 1
m = m if m > visited[ny][nx] else visited[ny][nx]
que.append([ny, nx])
for n in range(N):
if 0 in visited[n]:
return -1
else:
return m-1
for n in range(N):
if '0' in box[n]:
print(bfs())
exit(0)
else:
print(0)
3次元トマト問題は2次元で高さだけを増やす方向とfor文でif文を増やすと似た方向に戻ります.
for k in range(H):
temp =[]
for i in range(N):
tmp = list(sys.stdin.readline().split())
for j in range(M):
if '-1' == tmp[j]:
visited[k][i][j] = -1
elif '1' == tmp[j]:
que.append([k, i, j])
visited[k][i][j] = 1
temp.append(tmp)
box.append(temp)
input
3 Dリストを受信する過程で、1 Dリストをtmpリストに保存し、tmpを2 D tempリストに再保存するトラブルに遭遇しました。 tempリストをボックスに再保存することで解決しました。 △これよりもっといい方法があるようだが、まだ方法が見つからない。
# [백준] https://www.acmicpc.net/problem/7569 토마토(3차원)
# BFS '최소 날짜'
import sys
import collections
sys.stdin = open('test/04.txt')
M, N, H = list(map(int, sys.stdin.readline().split()))
box = []
que = collections.deque([])
visited = [[[0] * M for _ in range(N)] for _ in range(H)]
dx = [0, 0, -1, 1, 0, 0]
dy = [0, 0, 0, 0, -1, 1]
dh = [-1, 1, 0, 0, 0, 0]
m = 0
for k in range(H):
temp =[]
for i in range(N):
tmp = list(sys.stdin.readline().split())
for j in range(M):
if '-1' == tmp[j]:
visited[k][i][j] = -1
elif '1' == tmp[j]:
que.append([k, i, j])
visited[k][i][j] = 1
temp.append(tmp)
box.append(temp)
def bfs():
global m
while len(que) != 0:
h, y, x = que.popleft()
for i in range(6):
nh = h + dh[i]
nx = x + dx[i]
ny = y + dy[i]
if 0 <= ny < N and 0 <= nx < M and 0 <= nh < H:
if visited[nh][ny][nx] == 0 and box[nh][ny][nx] == '0':
box[nh][ny][nx] = 1
visited[nh][ny][nx] = visited[h][y][x] + 1
m = m if m > visited[nh][ny][nx] else visited[nh][ny][nx]
que.append([nh, ny, nx])
for h in range(H):
for n in range(N):
if 0 in visited[h][n]:
return -1
else:
return m-1
for h in range(H):
for n in range(N):
if '0' in box[h][n]:
print(bfs())
exit(0)
else:
print(0)
Reference
この問題について([白俊]7576&7569トマト🍅), 我々は、より多くの情報をここで見つけました https://velog.io/@crystalhwang16/백준-75767569-토마토テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol