시간제한 1초
문제
N개의 층에 각각 M개의 숫자가 쓰여있다. 회전탑은 층에 존재하는 숫자를 회전시킬 수 있다. 회전 후 인접한 부분의 숫자가 같을 경우 회전판에서 숫자를 지운다.
[그림 1]
회전탑의 회전은 시계 방향 혹은 반시계 방향으로 가능하다. 한 번 회전시 회전되는 층은 다수가 될 수 있다. 회전시켜야할 층의 번호와 배수관계에 있는 회전판들은 모두 회전된다. 또한, 회전은 동시에 일어난다. 층을 회전한 뒤 회전한 어떠한 층에서도 지워지는 숫자가 없을 경우, 모든 층에 존재하는 숫자들의 평균을 구해 각각의 숫자와 비교한다.(평균값의 소숫점 아래는 버린다) 만약 평균보다 크면 -1을, 평균보다 작으면 +1을 더해준다. 앞서 말한 처리를 한 다음엔 다시 제거가 일어나는 것이 아닌 다음 회전이 일어난다.
[그림 2]
[그림 3]
회전탑의 정보와 회전시키는 정보가 주어졌을때, 회전을 마친 뒤 탑에 남아있는 숫자들의 합을 구해보자.
입력
첫 번째 줄에 테스트 케이스의 개수 T가 주어진다. 다음 줄부터 T개의 테스트 케이스에 대한 정보가 주어진다.
각각의 테스트 케이스의 첫 번째 줄에 회전판의 개수 N, 각각의 회전판에 쓰여진 숫자 개수 M, 회전 횟수 K가 공백을 통해 구분하여 주어진다.
두 번째 줄부터 N개의 줄에 걸쳐 1층부터 N층까지 각 층의 회전판에 쓰여진 숫자가 공백을 통해 구분하여 주어진다. 주어진 순서대로 인접해있으며, 첫 번째 숫자가 12시 방향의 바로 오른쪽에 적힌다. 회전판에 적히는 숫자는 100을 넘지않는 자연수다.
바로 다음 줄부터 K개의 줄에 걸쳐 회전 정보가 공백을 통해 구분하여 주어진다. 각 줄에 주어지는 회전 정보는 회전시킬 층의 번호 a, 방향 d, 회전시킬 칸 수 c 순서로 주어진다. 회전 방향은 0과 1로 주어지며, 0은 시계 방향, 1은 반시계 방향이다. (3 ≤ N, M ≤ 50, 1 ≤ K ≤ 50, 1 ≤ a ≤ N, 1 ≤ c ≤ 50)
출력
각 테스트 케이스에 대해 회전을 마친 뒤 회전탑에 남은 숫자들의 합을 출력한다. 각 테스트 케이스의 출력 양식은 "#t r"이다. t는 테스트 케이스의 번호이며, 1부터 시작한다. r은 문제에 대한 결과값을 뜻한다.
예제 입력
5
4 5 2
4 3 6 1 3
3 2 6 3 2
6 5 1 9 7
2 9 8 3 8
2 0 1
1 0 1
4 5 2
4 3 6 1 3
3 2 6 3 2
6 5 1 9 7
2 9 8 3 8
2 1 2
1 0 1
3 7 5
7 4 9 2 9 5 7
9 3 5 6 5 9 3
4 4 3 9 7 4 2
3 1 8
2 1 1
1 0 6
1 1 7
3 0 8
9 5 4
10 7 9 9 7
5 2 8 2 3
7 4 9 10 4
9 6 2 4 4
9 10 10 5 5
8 5 4 2 4
9 5 4 10 6
8 6 8 9 10
10 9 2 8 9
7 1 10
5 1 2
2 0 9
4 0 8
7 7 1
1 1 2 6 2 7 6
4 9 9 7 9 1 1
4 8 3 5 6 9 5
9 1 2 6 1 6 4
7 1 2 2 1 6 2
5 10 1 3 8 7 9
3 10 2 9 3 2 2
6 0 10
예제 출력
#1 76
#2 74
#3 49
#4 133
#5 173
#코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
import sys
from collections import deque
# N개의 층에 각각 M개의 숫자가 쓰여있다
# 회전탑은 층에 존재하는 숫자를 회전시킬 수 있다.
# 회전 후 인접한 부분의 숫자가 같을 경우 회전판에서 숫자를 지운다.
# 회전은 시계 방향 혹은 반시계 방향으로 가능
# 한 번 회전시 회전되는 층은 다수가 될 수 있다.
# 회전시켜야할 층의 번호와 배수관계에 있는 회전판들은 모두 회전된다.
# 어떠한 층에서도 지워지는 숫자가 없을 경우,
# 모든 층에 존재하는 숫자들의 평균을 구해 각각의 숫자와 비교한다.(평균값의 소숫점 아래는 버린다)
# 만약 평균보다 크면 -1을, 평균보다 작으면 +1을 더해준다
# 앞서 말한 처리를 한 다음엔 다시 제거가 일어나는 것이 아닌 다음 회전이 일어난다.
# 회전탑의 정보와 회전시키는 정보가 주어졌을때, 회전을 마친 뒤 탑에 남아있는 숫자들의 합을 구해보자.
def push(frame, moveInfo):
a = moveInfo[0] # 회전시킬 층의 번호
d = moveInfo[1] # 방향 0 : 시계방향(-1), 1 : 반시계방향(1)
c = moveInfo[2] # 회전시킬 칸 수
# 1. 회전 시킨다.
for i in range(1, len(frame)+1):
if i%a == 0:
deq = deque(frame[i-1])
# 시계 방향
if d == 0:
deq.rotate(c)
# 반시계 방향
if d == 1:
temp = c*(-1)
deq.rotate(temp)
frame[i-1] = deq
# 2. 인접 녀석들을 지운다. 지워지는 요소들은 카운팅 하지 않도록 주의!
# cnt를 체크해서 0인 경우 평균값을 구한다.
# 평균보다 크면 -1을, 평균보다 작으면 +1을 더해준다
# 상, 하, 좌, 우 비교
# 좌-우는 이어져 있으나, 상-하는 이어져 있지 않다.
# 배열 복사본을 만들어 없어지는 경우를 표시
'''
4 3 6 1 3
2 6 3 2 3
6 5 1 9 7
9 8 3 8 2
'''
cnt = 0
temp_matrix = [[False]*m for _ in range(n)] # 없어 졌으면 True
# 상 하 좌 우
dy = [-1, 1, 0, 0]
dx = [0, 0, -1, 1]
outline = [[-1]*(m) for _ in range(n+2)]
for i in range(n):
for j in range(m):
outline[i+1][j] = frame[i][j]
for i in range(1, n+1):
for j in range(m):
tempTop = dy[0] + i
tempDown = dy[1] + i
tempLeft = dx[2] + j
if tempLeft <= -1:
tempLeft = m-1
tempRight = dx[3] + j
if tempRight >= m:
tempRight = 0
if outline[i][j] == outline[tempTop][j] or outline[i][j] == outline[tempDown][j] or outline[i][j] == outline[i][tempLeft] or outline[i][j] == outline[i][tempRight]:
if outline[i][j] != 0:
temp_matrix[i-1][j] = True
cnt += 1
for i in range(n):
for j in range(m):
if temp_matrix[i][j] == True:
frame[i][j] = 0
# 어떠한 층에서도 지워지는 숫자가 없을 경우,
if cnt == 0:
avgCnt = 0
sum = 0
for i in range(n):
for j in range(m):
if frame[i][j] != 0:
avgCnt += 1
sum += frame[i][j]
# 모든 층에 존재하는 숫자들의 평균을 구해 각각의 숫자와 비교한다.(평균값의 소숫점 아래는 버린다)
avg = sum//avgCnt
# 만약 평균보다 크면 -1을, 평균보다 작으면 +1을 더해준다
# 앞서 말한 처리를 한 다음엔 다시 제거가 일어나는 것이 아닌 다음 회전이 일어난다.
for i in range(n):
for j in range(m):
if frame[i][j] == 0: continue
if frame[i][j] > avg:
frame[i][j] -= 1
if frame[i][j] < avg:
frame[i][j] += 1
return frame
if __name__ == "__main__":
input = sys.stdin.readline
t = int(input())
for aa in range(t):
n, m, k = map(int, input().split())
frameInfo = [list(map(int, input().split())) for _ in range(n)]
moveInfo = [list(map(int, input().split())) for _ in range(k)]
for i in moveInfo:
frameInfo = push(frameInfo, i)
sum = 0
for i in frameInfo:
for j in i:
sum += j
print('#' + str(int(aa+1)) + ' ' + str(sum))
|
cs |