일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 헬스
- LG글로벌챌린저
- 테를지
- 아부다비
- 소프트웨어 아카데미
- 칭기스칸 동상
- 게르
- Python
- 월드프렌즈 ICT 봉사단
- ICT봉사단
- 한 줄로 서기
- 몽골 헬스장
- 독일
- 알고리즘
- 테를지국립공원
- 교환학생
- 여행
- 몽골 고기
- 초원
- 몽골
- 몽골요리
- 파이썬
- 울란바토르
- 담슈타트
- algorithm
- 월드프렌즈
- 칭기즈칸
- 코로나
- SWEA
- 백준
- Today
- Total
맛있는물회
[맛있는물회] [파이썬] <백준 알고리즘> 2589번 "보물섬" 본문
문제 조건
보물섬 지도를 발견한 후크 선장은 보물을 찾아나섰다. 보물섬 지도는 아래 그림과 같이 직사각형 모양이며 여러 칸으로 나뉘어져 있다. 각 칸은 육지(L)나 바다(W)로 표시되어 있다. 이 지도에서 이동은 상하좌우로 이웃한 육지로만 가능하며, 한 칸 이동하는데 한 시간이 걸린다. 보물은 서로 간에 최단 거리로 이동하는데 있어 가장 긴 시간이 걸리는 육지 두 곳에 나뉘어 묻혀있다. 육지를 나타내는 두 곳 사이를 최단 거리로 이동하려면 같은 곳을 두 번 이상 지나가거나, 멀리 돌아가서는 안 된다.
예를 들어 위와 같이 지도가 주어졌다면 보물은 아래 표시된 두 곳에 묻혀 있게 되고, 이 둘 사이의 최단 거리로 이동하는 시간은 8시간이 된다.
보물 지도가 주어질 때, 보물이 묻혀 있는 두 곳 간의 최단 거리로 이동하는 시간을 구하는 프로그램을 작성하시오.
Input
첫째 줄에는 보물 지도의 세로의 크기와 가로의 크기가 빈칸을 사이에 두고 주어진다. 이어 L과 W로 표시된 보물 지도가 아래의 예와 같이 주어지며, 각 문자 사이에는 빈 칸이 없다. 보물 지도의 가로, 세로의 크기는 각각 50이하이다.
Output
첫째 줄에 보물이 묻혀 있는 두 곳 사이를 최단 거리로 이동하는 시간을 출력한다.
생각한 아이디어
맨첨에 단순하게 2중 포문 사용하면서 L이면 모두다 bfs를 돌면서 최대값을 체크했다.
근데 시간초과가 발생하길래 아 단순한 문제가 아니구나! 라는 생각을 하고
접근법을 바꾸었다.
섬들을 그룹화 하고, 그 그룹에서 bfs를 한번 실행한다. 그러면 bfs를 통해서 섬의 제일 끝점이 나오게된다.
그 끝점에서 다시 bfs를 돌리면 제일 긴 거리를 찾을 수 있다.
그렇게 힘들게 코딩했는데 틀렸다고 나온다. ㅎㅎㅎ
예외가 있었다.
ㅇㅇㅇㅇㅇㅇ
ㅇ ㅇ
ㅇㅇㅇㅇㅇㅇ
이런 경우에는 젤 끝점이 아니라 시작하는 위치에 따라서 아랫변의 중간 지점이 나올 수도 있다는 것이다.!!!
이런 경우가 예외였다... 그래서 하.. 하다가 조금 힌트를 얻었는데 맨첨에 시도한 단순한 bfs가 맞는 것이었다...
근데 계속 시간초과가 발생했다.
나는 visited를 리스트로 만들어서 append하고, 거리는 check 이차원 배열을 만들어서 계속 1씩 더해주는 방법을 사용했다.
이 부분에서 list 로 append해서 하지 않고 True False로 하니깐 맞다고 나온다....
백준 시간초과 넘 빡빡하다....ㅠㅠ
틀린 소스코드
#2589 보물섬
import sys
from collections import deque
input=sys.stdin.readline
dy=[-1,1,0,0]
dx=[0,0,-1,1]
def paint(y,x,MAP,row,col,idx):
queue=deque()
queue.append((y,x))
visited=[[y,x]]
while queue:
y,x=queue.popleft()
MAP[y][x]=idx
for dir in range(0,4):
ny,nx=y+dy[dir],x+dx[dir]
if row>ny>=0 and col>nx>=0 and [ny,nx] not in visited:
if MAP[ny][nx]=='L':
queue.append((ny,nx))
visited.append([ny,nx])
return MAP
def bfs(sy,sx,MAP,row,col,idx):
queue=deque()
queue.append((sy,sx))
visited=[[sy,sx]]
check=[[0 for _ in range(col)] for _ in range(row)]
while queue:
y,x=queue.popleft()
for dir in range(0,4):
ny,nx=y+dy[dir],x+dx[dir]
if row>ny>=0 and col>nx>=0 and [ny,nx] not in visited:
if MAP[ny][nx]==idx:
queue.append((ny,nx))
visited.append([ny,nx])
check[ny][nx]=check[y][x]+1
res,index=0,[sy,sx]
for y in range(0,row):
for x in range(0,col):
if check[y][x] > res:
index=[y,x]
res=check[y][x]
return [index,res]
if __name__ == "__main__":
row,col=map(int,input().split()) #세로 가로
MAP=[list(input().rstrip()) for _ in range(row)]
ans=0
idx=1
for y in range(0,row):#섬 끼리 그룹화
for x in range(0,col):
if MAP[y][x] == 'L':
MAP = paint(y,x,MAP,row,col,idx)
idx+=1
break
island_count = idx
for idx in range(1,island_count):
#젤 끝 위치를 찾는다
flag=0
for y in range(0,row):
for x in range(0,col):
if MAP[y][x] == idx:
#ans = max(ans,bfs(y,x,MAP,row,col))
res = bfs(y,x,MAP,row,col,idx)
target_idx = res[0]
flag=1
break
if flag==1:
break
res=bfs(target_idx[0],target_idx[1],MAP,row,col,idx)
ans = max(ans,res[1])
print(ans)
맞은 소스코드
#2589 보물섬
import sys
from collections import deque
input=sys.stdin.readline
dy=[-1,1,0,0]
dx=[0,0,-1,1]
def bfs(y,x,MAP,row,col):
queue=deque()
queue.append((y,x))
res=0
check=[[0 for _ in range(col)] for _ in range(row)]
check[y][x]=1
while queue:
y,x=queue.popleft()
for dir in range(0,4):
ny,nx=y+dy[dir],x+dx[dir]
if row>ny>=0 and col>nx>=0 and [ny,nx] and check[ny][nx]==0:
if MAP[ny][nx]=='L':
queue.append((ny,nx))
check[ny][nx]=check[y][x]+1
res=max(res,check[ny][nx])
return res-1
if __name__ == "__main__":
row,col=map(int,input().split()) #세로 가로
MAP=[list(input().rstrip()) for _ in range(row)]
ans=0
for y in range(0,row):
for x in range(0,col):
if MAP[y][x] == 'L':
ans = max(ans,bfs(y,x,MAP,row,col))
print(ans)
*파이썬 문법 정리
'IT > 알고리즘' 카테고리의 다른 글
[맛있는물회] [파이썬] <백준 알고리즘> 2636, 2638번 "치즈" (0) | 2020.06.01 |
---|---|
[맛있는물회] [파이썬] <백준 알고리즘> 2631번 "줄세우기" (LIS 알고리즘) (0) | 2020.06.01 |
[맛있는물회] [파이썬] <백준 알고리즘> 2493번 "탑" (0) | 2020.06.01 |
[맛있는물회] [파이썬] <백준 알고리즘> 2225번 "합분해" (0) | 2020.05.31 |
[맛있는물회] [파이썬] <백준 알고리즘> 1963번 "소수 경로" (0) | 2020.05.31 |