코딩테스트

[백준][구현] 원판 돌리기

pythaac 2022. 4. 28. 20:57
BAEKJOON Online Judge(BOJ) 문제입니다.

https://www.acmicpc.net/

 

Baekjoon Online Judge

Baekjoon Online Judge 프로그래밍 문제를 풀고 온라인으로 채점받을 수 있는 곳입니다.

www.acmicpc.net

 

문제

https://www.acmicpc.net/problem/17822

 

17822번: 원판 돌리기

반지름이 1, 2, ..., N인 원판이 크기가 작아지는 순으로 바닥에 놓여있고, 원판의 중심은 모두 같다. 원판의 반지름이 i이면, 그 원판을 i번째 원판이라고 한다. 각각의 원판에는 M개의 정수가 적혀

www.acmicpc.net

 

내가 작성한 코드

from collections import defaultdict, deque

dir = [(0, 1), (1, 0), (0, -1), (-1, 0)]

def read_data():
    N, M, T = map(int, input().rstrip().split())
    board = []
    for _ in range(N):
        board.append(list(map(int, input().rstrip().split())))
    rotate_info = []
    for _ in range(T):
        rotate_info.append(list(map(int, input().rstrip().split())))
    return N, M, board, rotate_info

def rotate(x, d, k, board, N, M):
    for r in range(x-1, N, x):
        # 시계
        if d == 0:
            board[r] = board[r][M-k:] + board[r][:M-k]
        # 반시계
        else:
            board[r] = board[r][k:] + board[r][:k]

def get_coord(r, c, d, N, M):
    nw_r, nw_c = r+dir[d][0], c+dir[d][1]
    if nw_r == -1:
        return None, None
    elif nw_r == N:
        return None, None
    if nw_c == -1:
        nw_c = M-1
    elif nw_c == M:
        nw_c = 0
    return nw_r, nw_c

def remove_injacent(board, r, c, N, M, q):
    v = board[r][c]

    for d in range(4):
        nw_r, nw_c = get_coord(r, c, d, N, M)
        if nw_r is not None and board[nw_r][nw_c] == v:
            q[(nw_r, nw_c)] = True
            q[(r, c)] = True

def remove(board, N, M):
    q = defaultdict(bool)
    for i in range(N):
        for j in range(M):
            if board[i][j] != 'x':
                remove_injacent(board, i, j, N, M, q)

    for k, v in q.items():
        if v:
            board[k[0]][k[1]] = 'x'

    if not q:
        sm, cnt = get_sum(board, N, M)
        avg = sm / cnt if sm != 0 else 0
        for i in range(N):
            for j in range(M):
                if board[i][j] != 'x' and board[i][j] > avg:
                    board[i][j] -= 1
                elif board[i][j] != 'x' and board[i][j] < avg:
                    board[i][j] += 1

def get_sum(board, N, M):
    total = 0
    cnt = 0
    for i in range(N):
        for j in range(M):
            if board[i][j] != 'x':
                total += board[i][j]
                cnt += 1
    return total, cnt

def get_answer(N, M, board, rotate_info):
    for x, d, k in rotate_info:
        rotate(x, d, k, board, N, M)
        remove(board, N, M)
        # debug(board)
    return get_sum(board, N, M)[0]

def debug(board):
    print(f"==========================")
    for z in board:
        print(z)
    print()

def test():
    N, M, T = 50,50,50
    board = [[1000 - (i + j) for i in range(M)] for j in range(N)]
    rotate_info = [[i % (N-2) + 2, i%2, i % (M-1) + 1] for i in range(T)]

    return N, M, board, rotate_info

N, M, board, rotate_info = read_data()
# N, M, board, rotate_info = test()
print(get_answer(N, M, board, rotate_info))
  • 인접
    • column은 circular, row는 x
  • ZeroDivisionError
    • sum == 0 일 때 처리 필요

 

다른 사람이 작성한 코드

None
  • 강한 구현문제로 다른 코드를 참고하지 않음

 

기억해야할 것