Computer Science/알고리즘

[백준 - Python] 17822 - 원판 돌리기

바보1 2023. 2. 23. 16:43

0.  문제 링크

 

 

 

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

 

17822번: 원판 돌리기

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

www.acmicpc.net


1.  풀이 방법

 

 

우선 배열을 돌린다, 회전한다 뭐 이런거는 너무 오래 걸릴 것 같았다.

그래서 12시 방향을 시작점으로 하고, 그 좌표를 저장하는게 좋아보였다.

그래서 결국엔 다 풀었는데, 뭔가 마지막 예제가 계속 안 됐었다.

알고보니까 인접한 모든 애들을 없애야 하는 것이 있었다.

여기서 다시 BFS로 풀자니 푼 시간이 아깝고, 다시 구현하기도 귀찮았다.

그래서 그냥 새로운 변수 하나 만들어서 거기에 인접한 애들을 모두 저장하고, 나중에 한 번에 바꾸는 방식을 썼다.

 

그 외엔 특별한 점 없음


2.  코드

 

 

read = lambda : map(int, input().split())
n, m, t = read()
num = [[0] * (n + 1)] + [list(read()) for _ in range(n)]        # 0번째 행은 어디가 첫 번째인지 확인하는 함수
temp = [[0] * m for _ in range(n + 1)]      # 인접하면서 같은 곳을 저장해놓음

for idx in range(1, t + 1):
    x, d, k = read()
    for i in range(x, n + 1, x):
        num[0][i - 1] = (num[0][i - 1] + (-1, 1)[d] * k) % m        # 방향을 돌림
    for i in range(1, n + 1):
        for j in range(m):
            if 0 != num[i][j] == num[i][val1 := (j + 1) % m]:
                temp[i][j] = temp[i][val1] = num[0][n] = idx        # 행에서 같은 애들
            if i != n and 0 != num[i][(val1 := (j + num[0][i - 1]) % m)] == num[i + 1][val2 := (j + num[0][i]) % m]:
                temp[i][val1] = temp[i + 1][val2] = num[0][n] = idx     # 열에서 같은 애들

    for i in range(1, n + 1):
        for j in range(m):
            if temp[i][j] == idx: num[i][j] = 0     # 인접하면서 같은 애들을 0으로 만듬

    if num[0][n] != idx:
        if s := sum([i.count(0) for i in temp[1:]]):        # Division by zero를 방지
            mean = sum([sum(i) for i in num[1:]]) / s       # 평균을 구함
        else:
            print(0)
            exit(0)
        for i in range(1, n + 1):
            for j in range(m):
                if val := num[i][j]:
                    num[i][j] = val + 1 if val < mean else val - 1 if val > mean else val

print(sum([sum(i) for i in num[1:]]))

3.  마무리