https://www.acmicpc.net/problem/17822
"""
"""
from collections import deque
N, M, T = map(int, input().split()) # N:반지름, M:정수의 개수, T:회전 횟수
circle = [ deque(map(int, input().split())) for _ in range(N) ] # 원판
spin = [ list(map(int, input().split())) for _ in range(T) ] # 회전 정보
def circle_rotate(x, d): # 원판을 회전 시켜주는 함수
for i in range(x, N+1, x): # x의 배수 만큼 원판 돌리기
if d == 0: # d=0이면 시계방향 회전
circle[i-1].rotate(1)
else: # d=-1이면 반시계방향 회전
circle[i-1].rotate(-1)
dx, dy = [0, 0, -1, 1], [-1, 1, 0, 0]
def circle_remove(r, c, num): # 인접한 곳에 같은 수가 2개 이상이면 수를 지우는 함수
global flag
visited[r][c] = True
q = deque([(r, c)])
remove_list = [(r, c)]
while q:
px, py = q.popleft()
for k in range(4):
mx = (px + dx[k])
my = (py + dy[k]) % M # ★ M의 나머지를 통해 첫번째 열과 마지막 열을 연결 시킴 ★
if 0 <= mx < N and 0 <= my < M:
if circle[mx][my] == num and not visited[mx][my]:
visited[mx][my] = True
remove_list.append((mx, my))
q.append((mx, my))
if len(remove_list) >= 2: # 만약 인접한 수가 2개 이상이라면 지움
for a, b in remove_list:
circle[a][b] = 0 # 지운 곳은 0으로 기록
flag = True
def circle_avg(): # 수를 지우지 못한 경우 평균을 구해서 평균보다 작은경우 +1, 큰 경우 -1을 하는 함수
total = 0
cnt = 0
for i in range(N):
for j in range(M):
if circle[i][j] > 0:
total += circle[i][j]
cnt += 1
if cnt != 0: # ★ 만약 아무 수가 없다면 cnt가 0이라 zerodivision이 되므로 조심하기 ★
avg = total / cnt
for i in range(N):
for j in range(M):
if circle[i][j] > 0:
if circle[i][j] > avg:
circle[i][j] -= 1
elif circle[i][j] < avg:
circle[i][j] += 1
for x, d, k in spin: # x의 배수의 원판, d:0->시계 1->반시계, k:돌아가는 칸수
# 1. 번호가 xi의 배수인 원판을 di방향으로 ki칸 회전시킨다. di가 0인 경우는 시계 방향, 1인 경우는 반시계 방향이다.
for _ in range(k): # k칸 만큼 회전
circle_rotate(x, d)
# print(circle)
# 2. 원판에 수가 남아 있으면, 인접하면서 수가 같은 것을 모두 찾아 지운다.
visited = [ [False] * M for _ in range(N) ]
flag = False # 원판에서 수를 지웠는지 체크하는 변수
for i in range(N):
for j in range(M):
if circle[i][j] > 0:
circle_remove(i, j, circle[i][j])
# print(circle, flag)
# 2-1. 인접하면서 같은 수가 없는 경우에는 원판에 적힌 수의 평균을 구하고, 평균보다 큰 수에서 1을 빼고, 작은 수에는 1을 더한다.
if flag == False:
circle_avg()
answer = sum( sum(x) for x in circle )
print(answer)
deque()의 rotate() -> rotate()안에 인자가 양수이면 시계 방향, 음수이면 반시계 방향 회전임.
circle_remove() 즉, BFS 부분에서 열 끼리 연결 시키기 위해 % M을 해줌. 이 부분 깊게 생각안하면 놓치기 쉬우므로 주의
my = (py + dy[k]) % M # ★ M의 나머지를 통해 첫번째 열과 마지막 열을 연결 시킴 ★