본문 바로가기
알고리즘/백준

[백준]230303-05 문제풀이

by stubborngastropod 2023. 3. 6.
728x90

19237. 어른 상어

import sys
input = sys.stdin.readline

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

def move(i, j):
    n = lst[i][j]
    for d in range(1, 5):
        yy = i + dy[D[n][now_D[n]][d]]
        xx = j + dx[D[n][now_D[n]][d]]
        if yy not in range(N) or xx not in range(N):
            continue
        if not smell[yy][xx]:
            now_D[n] = D[n][now_D[n]][d]
            return yy, xx

    for d in range(1, 5):
        yy = i + dy[D[n][now_D[n]][d]]
        xx = j + dx[D[n][now_D[n]][d]]
        if yy not in range(N) or xx not in range(N):
            continue
        if smell[yy][xx][0] == n:
            now_D[n] = D[n][now_D[n]][d]
            return yy, xx

N, M, k = map(int, input().split())
lst = [list(map(int, input().split())) for _ in range(N)]
smell = [[[] for _ in range(N)] for __ in range(N)]
now_D = [0] + list(map(int, input().split()))

D = [[]]
for _ in range(M):
    temp_D = [[0] * M]
    for __ in range(4):
        temp_D.append([0] + list(map(int, input().split())))
    D.append(temp_D)
time = 0
shark = M

while shark > 1 and time <= 1000:
    time += 1
    # 냄새 처리
    for i in range(N):
        for j in range(N):
            if smell[i][j]:
                smell[i][j][1] -= 1
                if not smell[i][j][1]:
                    smell[i][j].clear()
            if lst[i][j]:
                smell[i][j] = [lst[i][j], k]
    # 이동
    temp = [[0] * N for _ in range(N)]
    for i in range(N):
        for j in range(N):
            if lst[i][j]:
                y, x = move(i, j)
                if temp[y][x]:
                    if temp[y][x] > lst[i][j]:
                        temp[y][x] = lst[i][j]
                    shark -= 1
                else:
                    temp[y][x] = lst[i][j]
    lst = temp
if time > 1000:
    print(-1)
else:
    print(time)

먼저 문제에서 상어가 움직이는 로직을 잘 이해하는게 중요하다. 냄새가 없거나 자신의 냄새가 있는 곳으로만 이동해야 하므로 냄새에 대한 처리를 먼저 해준 후 다같이 이동하기 위해 temp를 사용해서 저장했다가 한꺼번에 위치를 바꿔준다. 이 때 상어의 위치를 3차원 배열로 저장해서 상어가 두 마리 저장되어 있을 때 숫자가 큰 상어를 제거해 주는 식으로 구현했다. 조건이 까다롭다기보다는 구현 순서를 어떻게 하는지, 냄새와 상어 위치를 어떻게 저장할지가 관건인 문제였다.

2567. 색종이 - 2

import sys
input = sys.stdin.readline

dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
paper = [[0] * 100 for _ in range(100)]
n = int(input())
for color in range(n):
    a, b = map(int, input().split())
    for i in range(10):
        for j in range(10):
            paper[a + i][99 - b - j] = 1

ans = 0
for r in range(100):
    for c in range(100):
        if paper[r][c]:
            cnt = 0
            for d in range(4):
                if r + dx[d] not in range(100) or c + dy[d] not in range(100)\
                    or paper[r + dx[d]][c + dy[d]] == 0:
                    cnt += 1
            if cnt == 1:
                ans += 1
            if cnt == 2:
                ans += 2
print(int(ans))

뭔가 풀고나서 풀이과정을 신박하게 했다고 생각했다. 다른 사람들도 다 이렇게 했을진 모르지만... 배열을 그리드라고 생각하고 색종이를 모두 붙인 다음 델타를 돌려서 상하좌우로 비어있는 칸이 1개면 길이 + 1, 2개면 길이 + 2 이런 식으로 계산했다. 경계값 처리만 주의해주면 간단한 로직 완성

12100. 2048(Easy)

import sys
input = sys.stdin.readline

N = int(input())
lst = [list(map(int, input().split())) for _ in range(N)]
ans = 0

def up(board):
    global ans
    new = [[0] * N for _ in range(N)]
    for i in range(N):
        cnt = 0
        for j in range(N):
            if board[j][i] and cnt % 2:
                if new[cnt // 2][i] == board[j][i]:
                    new[cnt // 2][i] += board[j][i]
                    if new[cnt // 2][i] > ans:
                        ans = new[cnt // 2][i]
                    cnt += 1
                else:
                    cnt += 1
                    new[cnt // 2][i] = board[j][i]
                    if new[cnt // 2][i] > ans:
                        ans = new[cnt // 2][i]
                    cnt += 1
            elif board[j][i] and not cnt % 2:
                new[cnt // 2][i] = board[j][i]
                if new[cnt // 2][i] > ans:
                    ans = new[cnt // 2][i]
                cnt += 1
    return new

def down(board):
    global ans
    new = [[0] * N for _ in range(N)]
    for i in range(N):
        cnt = 0
        for j in range(N - 1, -1, -1):
            if board[j][i] and cnt % 2:
                if new[N - 1 - (cnt // 2)][i] == board[j][i]:
                    new[N - 1 - (cnt // 2)][i] += board[j][i]
                    if new[N - 1 - (cnt // 2)][i] > ans:
                        ans = new[cnt // 2][i]
                    cnt += 1
                else:
                    cnt += 1
                    new[N - 1 - (cnt // 2)][i] = board[j][i]
                    if new[N - 1 - (cnt // 2)][i] > ans:
                        ans = new[cnt // 2][i]
                    cnt += 1
            elif board[j][i] and not cnt % 2:
                new[N - 1 - (cnt // 2)][i] += board[j][i]
                if new[N - 1 - (cnt // 2)][i] > ans:
                    ans = new[N - 1 - (cnt // 2)][i]
                cnt += 1
    return new

def left(board):
    global ans
    new = [[0] * N for _ in range(N)]
    for i in range(N):
        cnt = 0
        for j in range(N):
            if board[i][j] and cnt % 2:
                if new[i][cnt // 2] == board[i][j]:
                    new[i][cnt // 2] += board[i][j]
                    if new[i][cnt // 2] > ans:
                        ans = new[i][cnt // 2]
                    cnt += 1
                else:
                    cnt += 1
                    new[i][cnt // 2] = board[i][j]
                    if new[i][cnt // 2] > ans:
                        ans = new[i][cnt // 2]
                    cnt += 1
            elif board[i][j] and not cnt % 2:
                new[i][cnt // 2] = board[i][j]
                if new[i][cnt // 2] > ans:
                    ans = new[i][cnt // 2]
                cnt += 1
    return new

def right(board):
    global ans
    new = [[0] * N for _ in range(N)]
    for i in range(N):
        cnt = 0
        for j in range(N - 1, -1, -1):
            if board[i][j] and cnt % 2:
                if new[i][N - 1 - (cnt // 2)] == board[i][j]:
                    new[i][N - 1 - (cnt // 2)] += board[i][j]
                    if new[i][N - 1 - (cnt // 2)] > ans:
                        ans = new[i][N - 1 - (cnt // 2)]
                    cnt += 1
                else:
                    cnt += 1
                    new[i][N - 1 - (cnt // 2)] = board[i][j]
                    if new[i][N - 1 - (cnt // 2)] > ans:
                        ans = new[i][N - 1 - (cnt // 2)]
                    cnt += 1
            elif board[i][j] and not cnt % 2:
                new[i][N - 1 - (cnt // 2)] = board[i][j]
                if new[i][N - 1 - (cnt // 2)] > ans:
                    ans = new[i][N - 1 - (cnt // 2)]
                cnt += 1
    return new

def game(board, c):
    if c == 5:
        return
    game(up(board), c + 1)
    game(down(board), c + 1)
    game(left(board), c + 1)
    game(right(board), c + 1)
number = 1
game(lst, 0)
print(ans)

풀이과정은 번뜩! 하고 떠올랐으나 코드가 너무 길다보니 범위 설정에 대한 오타를 찾기가 힘들어서 고생했다. 가령 range에서 역순으로 해줬으면 밑에서 index는 원래 순서대로 해줘야 하는데 그런 부분이나 x, y 좌표를 혼동하는 부분들이 그랬다. 복붙의 부작용을 심하게 경험했던 문제... 그래도 재미는 있었다.

728x90

'알고리즘 > 백준' 카테고리의 다른 글

[백준]230310-12 문제풀이  (0) 2023.03.13
[백준]230306-09 문제풀이  (0) 2023.03.10
[백준]230302 문제풀이  (2) 2023.03.02
[백준]230228-0301 문제풀이  (0) 2023.03.01
[백준]230226 문제풀이  (0) 2023.02.26

댓글