취준/백준

[백준][Python][17822][구현] 원판 돌리기

puff 2020. 3. 13. 21:32

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

 

17822번: 원판 돌리기

반지름이 1, 2, ..., N인 원판이 크기가 작아지는 순으로 바닥에 놓여있고, 원판의 중심은 모두 같다. 원판의 반지름이 i이면, 그 원판을 i번째 원판이라고 한다. 각각의 원판에는 M개의 정수가 적혀있고, i번째 원판에 적힌 j번째 수의 위치는 (i, j)로 표현한다. 수의 위치는 다음을 만족한다. (i, 1)은 (i, 2), (i, M)과 인접하다. (i, M)은 (i, M-1), (i, 1)과 인접하다. (i, j)는 (i, j-1), (i, j

www.acmicpc.net

구현 문제다.

 

우선, 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))