developer-ellen
인간 디버거의 로그 찍기
developer-ellen
전체 방문자
오늘
어제
  • 분류 전체보기 (217)
    • 회고록 (0)
    • 취뽀 및 커리어 여정의 Stack (2)
      • SSAFY 7기 (2)
    • 프로그래밍공부 (24)
      • c++ (0)
      • JAVA (3)
      • Spring (5)
      • design pattern (3)
      • BackDB (1)
      • Servlet&JSP (3)
      • Vue (4)
      • JPA (4)
      • Infra (1)
      • Linux (0)
    • AI (3)
      • papers (3)
      • trend (0)
    • 프로젝트진행 (0)
      • 데이터베이스 (0)
      • 서버개발 (0)
      • 인공지능 (0)
      • 하루정리 (0)
    • 포트폴리오 (0)
    • 알고리즘 (158)
      • 알고리즘문풀 (155)
      • 알고리즘공부 (3)
    • 통계공부 (15)
      • 시계열분석 (15)
      • 회귀분석 (0)
    • CS (14)
      • 컴퓨터네트워크 (4)
      • 운영체제 (8)
      • 데이터베이스 (2)
    • 주저리주저리 (0)
      • 필사 (0)
    • 취업관련정보 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 카카오코테
  • 시계열분석
  • MA모형
  • 데이터분석
  • BOJ파이썬풀이
  • 삼성코테파이썬준비
  • 코테파이썬
  • 삼성코테파이썬풀이
  • c++ 빌더 패턴
  • 삼성코테구현문제추천
  • 카카오코테java풀이
  • 통계학
  • 삼성코테기출
  • 통계분석
  • 백준파이썬풀이
  • 삼성코테기출자바풀이
  • ARIMA모형
  • 운영체제인터럽트
  • 삼성코테자바준비
  • c++디자인패턴
  • SW역량테스트파이썬풀이
  • Arima
  • 삼성코테준비
  • 삼성코테파이썬
  • SW역량테스트파이썬
  • 삼성코테자바풀이
  • 삼성코테구현풀이
  • AR모형
  • 삼성코테자바꿀팁
  • 시계열

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
developer-ellen

인간 디버거의 로그 찍기

알고리즘/알고리즘문풀

BOJ - 어른 상어 19237번 (python)

2021. 10. 20. 11:36

❓ 문제 - 백준 어른 상어 19237번 - python 풀이법

 

출처 

(https://www.acmicpc.net/problem/19237)

 

19237번: 어른 상어

첫 줄에는 N, M, k가 주어진다. (2 ≤ N ≤ 20, 2 ≤ M ≤ N2, 1 ≤ k ≤ 1,000) 그 다음 줄부터 N개의 줄에 걸쳐 격자의 모습이 주어진다. 0은 빈칸이고, 0이 아닌 수 x는 x번 상어가 들어있는 칸을 의미

www.acmicpc.net

 

 

 

📝 문제해결법

1. 이 문제는 구현로 풀었다.

  • sea(격자칸에 상어의 번호로 존재 표시), smell(격자칸에 존재하는 상어의 냄새표현 위해 냄새 타이머, 상어의 번호), s_dir(현재 상어의 방향), dir(상어의 번호와 상어의 현재방향에 따른 다음 방향 정보) 리스트를 활용하여 문제를 푼다.
  • count로 초 수를 세고, 만약 이동이 1000초 이상되었다면 -1을 출력한다. while 문을 돌면서 s_smell() 함수로 현재 상어의 위치에 냄새를 뿌리고, move() 함수로 상어의 이동을 처리한다. 또한 상어 이동시, 퇴출되는 상어의 수를 카운트 하여, 만약 이동이 끝난 후 퇴출된 상어의 수가 (m-1)개, 즉 상어 1만 남아있으면 while문을 빠져나와 count(정답)을 출력한다.
  • 만약 이동이 끝났는데도 격자판에 상어 1 이외에 다른 상어도 존재하면 뿌린냄새의 타이머를 -1 해준다.

2. move()

  • 상어 이동이 한 초에 한번에 이루어지므로 이동에 s 리스트를 이용한다.
  • 모든 격자판을 돌면서 상어가 존재한다면, 해당 위치의 상어의 번호와 그 상어의 방향 정보를 가져온다.
  • 상어의 번호와 현재 방향 정보에 해당하는 우선순위로 4방향을 탐색하면서 먼저 4방향에 위치가 격자판 범위 내에서, 상어의 냄새가 존재하지 않을 때 이동할 위치에 만약 상어가 존재하지 않다면 해당 위치로 상어를 이동시켜준다. 만약 해당 위치에 상어가 존재한다면 상어의 숫자를 비교해서 숫자가 더 크다면 그 상어를 퇴출 시키고 퇴출 상어 수를 1 증가시킨다.
  • 만약 4방향 다 탐색했는데 모두 상어의 냄새가 존재한다면, 다시 우선순위에 맞춰 4방향을 탐색하면서 상어의 냄새가 현재 상어 번호에 해당하는 냄새라면 그 곳으로 이동한다.
  • 모든 이동 처리 후 원래 격자판 정보를 s(이동 후 격자판 정보)로 변경해준다.

3. 문제 풀면서 느낀점

  • 이동이나 구현시에 고려해야할 요소가 많을 때 해당 정보를 저장할 리스트를 만들어서 처리해야겠다.
  • 또한 한번에 이동이 일어나는 경우 이동을 위해 선언한 리스트와 과 이동 전 상태의 리스트를 분리시켜 처리해야한다.

 

💻 소스코드

import copy

n, m, k = map(int, input().split())
sea = [list(map(int, input().split())) for _ in range(n)]
smell = [[[0, 0] for _ in range(n)] for _ in range(n)]

s_dir = [0] + list(map(int, input().split()))

dir = [[]]
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]

for i in range(m):
    array = []
    for j in range(4):
        array.append(list(map(int, input().split())))
    dir.append(array)

def move(sea):
    global out
    s = copy.deepcopy(sea)
    for i in range(n):
        for j in range(n):
            if sea[i][j] == 0:
                continue
            s_n = s[i][j]
            d = s_dir[s_n]
            x, y = i, j
            what = False
            for p in range(4):
                nd = dir[s_n][d-1][p]
                nx = x + dx[nd-1]
                ny = y + dy[nd-1]
                if not(0<=nx<n and 0<= ny<n):
                    continue
                if smell[nx][ny][1] == 0:
                    if s[nx][ny] == 0:
                        s[nx][ny] = sea[x][y]
                        s[x][y] = 0
                    else:
                        if s[nx][ny] > s[x][y]:
                            s[nx][ny] = sea[x][y]
                        out += 1
                        s[x][y] = 0
                    s_dir[s_n] = nd
                    what = True
                    break
            if what:
                continue

            for p in range(4):
                nd = dir[s_n][d-1][p]
                nx = x + dx[nd - 1]
                ny = y + dy[nd - 1]
                if not (0 <= nx < n and 0 <= ny < n):
                    continue
                if smell[nx][ny][1] == s_n:
                    s[nx][ny] = sea[x][y]
                    s[x][y] = 0
                    s_dir[s_n] = nd
                    break
    return s

def s_smell(k):
    for i in range(n):
        for j in range(n):
            if sea[i][j] != 0:
                smell[i][j][0], smell[i][j][1] = k, sea[i][j]

def smell_down():
    for i in range(n):
        for j in range(n):
            if smell[i][j][1] == 0:
                continue
            if smell[i][j][0] == 1:
                smell[i][j][0], smell[i][j][1] = 0, 0
            else:
                smell[i][j][0] -= 1

count = 0
out = 0
while True:
    if count >= 1000:
        count = -1
        break
    s_smell(k)
    sea = copy.deepcopy(move(sea))
    count += 1
    if out == m-1:
        break
    smell_down()

print(count)

 

'알고리즘 > 알고리즘문풀' 카테고리의 다른 글

BOJ - 컨베이어 벨트 위의 로봇 20055번 (python)  (0) 2021.10.20
BOJ - 스타트택시 19238번 (python)  (0) 2021.10.20
BOJ - 청소년 상어 19236번 (python)  (2) 2021.10.19
BOJ - 모노미노도미노2 20061번 (python)  (0) 2021.10.19
BOJ - 주사위 윷놀이 17825번 (python, JAVA)  (0) 2021.10.18
    '알고리즘/알고리즘문풀' 카테고리의 다른 글
    • BOJ - 컨베이어 벨트 위의 로봇 20055번 (python)
    • BOJ - 스타트택시 19238번 (python)
    • BOJ - 청소년 상어 19236번 (python)
    • BOJ - 모노미노도미노2 20061번 (python)
    developer-ellen
    developer-ellen

    티스토리툴바