취준/백준
[백준][Python][17822][구현] 원판 돌리기
puff
2020. 3. 13. 21:32
문제 : https://www.acmicpc.net/problem/17822
구현 문제다.
우선, clockwise, counterclockwise, allavg, allsum 함수는 아래와 같다.
- clockwise 시계방향 리스트 회전
- counterclockwise 반시계 방향 회전
- allavg 0을 제외한 전체 평균값
- allsum 전체 합
입력을 받은 뒤, 원판을 2차원 배열처럼 관리하면 편하다. 특히 파이썬은 리스트의 리스트로 구현하면 회전 함수 구하는데도 편하다.
우선, x, d, k를 입력으로 받아 x의 배수 원판을 k만큼 돌린다.
그 후, 인접한 수 중 같은 수를 0으로 처리하는데, 기본적으로 위아래 왼쪽 오른쪽을 체크하면 되지만, 리스트의 양 끝도 체크해야 한다.
따라서,
- 위 아래 왼쪽 오른쪽을 체크해서 같은 값이면 deletelist에 넣고
- 가장자리도 따로 체크해서 deletelist에 넣는다.
- 그리고, isdelete 변수를 통해 하나라도 지웠는지 아닌지를 파악한다.
마지막으로, 하나도 지운 수가 없을 경우 평균을 구하고 , 평균 기준에 따라 더하고 뺀다.
import sys
dx,dy = [0,0,1,-1],[1,-1,0,0]
def clockwise(l, a):
return l[-a:] + l[:-a]
def counterclockwise(l, a):
return l[a:] + l[:a]
def allavg(a,arr):
ret, l = 0,0
for i in range(a):
for c in arr[i]:
if c !=0:
ret+=c
l+=1
if l==0:
return 0
return ret/l
def allsum(a,arr):
ret = 0
for i in range(a):
ret+=sum(arr[i])
return ret
n,m,t = [int(i) for i in sys.stdin.readline().split()]
rot = []
for _ in range(n):
rot.append([int(i) for i in sys.stdin.readline().split()])
for _ in range(t):
x,d,k = [int(i) for i in sys.stdin.readline().split()]
isDeleted = False
for i in range(1,n+1):
if i%x==0:
if d==0:
rot[i-1] = clockwise(rot[i-1], k)
else:
rot[i-1] = counterclockwise(rot[i-1], k)
deletelist = []
for i in range(n):
if rot[i][0] ==rot[i][-1]:
if rot[i][0] !=0:
isDeleted =True
deletelist.extend([[i,0],[i,-1]])
for i in range(n):
for j in range(m):
delflag = False
if rot[i][j]==0:
continue
for l in range(4):
nx,ny =j+dx[l], i+dy[l]
if 0<=ny < n and 0<=nx<m:
if rot[ny][nx] ==0:
continue
if rot[ny][nx] == rot[i][j]:
deletelist.append([ny,nx])
delflag = True
if delflag:
deletelist.append([i,j])
isDeleted = True
for i,j in deletelist:
rot[i][j] = 0
if not isDeleted:
avg = allavg(n,rot)
for i in range(n):
for j in range(m):
if rot[i][j] !=0:
if rot[i][j] < avg:
rot[i][j]+=1
elif rot[i][j] > avg:
rot[i][j]-=1
print(allsum(n,rot))