본문 바로가기
Algorithm/BOJ

[백준] 17822번 - 원판 돌리기 (파이썬)

by _temp 2022. 3. 8.

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

# 원판 돌리기
from collections import deque
import sys
intput = sys.stdin.readline
N, M, T = map(int, input().split())
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]

arr = []
for _ in range(N):
    arr.append(deque(map(int, input().split())))

order = []
for _ in range(T):
    order.append(list(map(int, input().split())))


def rolling(n, dir):
    for x in range(n, N+1, n):
        if dir == 0:
            temp = arr[x-1].pop()
            arr[x-1].appendleft(temp)
        else:
            temp = arr[x-1].popleft()
            arr[x-1].append(temp)


def breaking():
    change = []
    for i in range(N):
        for j in range(M):
            now = arr[i][j]
            if now == 'x':
                continue
            for k in range(4):
                nx = i + dx[k]
                ny = j + dy[k]
                if ny == -1 or ny == M:
                    if ny == -1:
                        ny = M-1
                    else:
                        ny = 0
                if 0 <= nx < N and 0 <= ny < M:
                    if now == arr[nx][ny]:
                        change.append((i, j))
                        change.append((nx, ny))
    if change:
        changing(change)
        return True
    else:
        return False


def changing(change):
    for x, y in change:
        arr[x][y] = 'x'


def dividing():
    sum = 0
    leng = 0
    for i in range(N):
        for j in range(M):
            if arr[i][j] != 'x':
                sum += arr[i][j]
                leng += 1
    if leng == 0:
        return
    avg = sum / leng
    for i in range(N):
        for j in range(M):
            if arr[i][j] != 'x':
                if arr[i][j] > avg:
                    arr[i][j] -= 1
                elif arr[i][j] < avg:
                    arr[i][j] += 1


for x, dir, k in order:
    for _ in range(k):
        rolling(x, dir)
    if not breaking():
        dividing()

result = 0
for i in range(N):
    for j in range(M):
        if arr[i][j] != 'x':
            result += arr[i][j]
print(result)

 

구현

1. rolling : x의 배수의 원을 dir방향으로 한 바퀴 회전

    - k 바퀴 반복

2. breaking : 인접한 같은 수들을 전부 'x'로 바꿔줌

    - 인접한 수들이 같다면 그 좌표들을 change 리스트에  append

    - changing : change 리스트의 모든 좌표들을 이용해서 값을 'x'로 바꿔줌

    - change 리스트가 있다면 changing 이후 return True (바뀌었다는 뜻)

    - change 리스트가 비어 있다면 return False

3. dividing : 평균값보다 큰 값은 -1, 작은 값은 +1

 

단순 구현(시뮬레이션)문제 이다. 삼성 SW 역량 기출문제답게 역시 빡구현 문제 중 하나

이런 문제들은 세세한 정보를 놓치지 않고 문제를 꼼꼼히 읽어야한다.

나중에 조건을 확인해서 아... 하는 경우가 다반사