본문 바로가기

알고리즘

[백준] 17822번 : 원판 돌리기

728x90

17822번: 원판 돌리기

 

17822번: 원판 돌리기

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

www.acmicpc.net

🤔 문제분석

원판을 구성하는걸 배열로 생각하여 문제를 해결하면 쉽게 해결 할 수 있습니다. i좌표는 첫번째와 마지막 좌표를 비교하지 않아야하고, i일때 (i+1, i-1) 만 비교하면된다. j좌표는 j가 0일때 M-1를 확인해야하고 j가 M-1일때 0을 확인해야하고 또한 j일때 (j+1, j-1) 확인해야한다.

위의 논리라면 filter 함수를 구현하였는데 filter는 x값을 -1이나 M으로 넘어가면 M-1, 0으로 치환해준다. ( j = (j+M) % M )

그 외에는 구현만 하면되는 문제라 딱히 어려울 것이 없다고 생각합니다.

💻 코드

import sys
from collections import deque
input = sys.stdin.readline
DIR = 0 # 시계방향
IN_DIR = 1 # 반시계방향

N, M, T = map(int, input().split())

graph = [deque(list(map(int, input().split()))) for _ in range(N)]

filter = lambda y, x : (y, (x+M) % M)
is_range = lambda y, x : (N > y >= 0 and M > x >=0)

def rotate(d, dir):
    if dir == DIR:
        graph[d].appendleft(graph[d].pop())
    else:
        graph[d].append(graph[d].popleft())

def find_near_num_and_avg():
    nums = set()
    moves = [(0, 1), (0, -1), (1, 0), (-1, 0)]
    total = 0
    cnt = 0
    for i in range(N):
        for j in range(M):
            if graph[i][j] != None:
                total += graph[i][j]
                cnt += 1
                for dy, dx in moves:
                    ny, nx = dy + i, dx + j
                    ny, nx = filter(ny, nx)
                    if graph[i][j] and is_range(ny, nx) and graph[ny][nx]:
                        if graph[i][j] == graph[ny][nx]:
                            nums.add((i, j))
                            nums.add((ny, nx))
    if cnt != 0:
        avg = total/cnt
    else:
        avg = 0
    return nums, avg

def no_number_command(avg):
    for i in range(N):
        for j in range(M):
            if graph[i][j] != None:
                if graph[i][j] > avg:
                    graph[i][j] -= 1
                elif graph[i][j] < avg:
                    graph[i][j] += 1

def sum_graph():
    total = 0
    for i in range(N):
        for j in range(M):
            if graph[i][j] != None:
                total += graph[i][j]
    
    return total

for _ in range(T):
    x, d, k = map(int, input().split())
    for i in range(x, N+1, x):
        for _ in range(k):
            rotate(i-1, d)
    
    nums, avg = find_near_num_and_avg()
    if len(nums) == 0:
        no_number_command(avg)
    else:
        for i, j in nums:
            graph[i][j] = None

print(sum_graph())

🎯 피드백 및 개선사항

한번에 문제를 해결하여서 기분이 좋네요~!

728x90

'알고리즘' 카테고리의 다른 글

[백준] 2174번 : 로봇 시뮬레이션  (0) 2024.02.02
[이것이코딩테스트다] 1로 만들기  (0) 2023.11.19
[알고리즘 - 이론] 분기한정법  (0) 2023.07.25
파이썬 공간복잡도  (0) 2023.06.24
파이썬 시간복잡도  (0) 2023.06.24