알고리즘/BOJ

[백준] 16926_배열 돌리기1

엉아_ 2021. 10. 25. 17:39
728x90

📕 문제

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

 

16926번: 배열 돌리기 1

크기가 N×M인 배열이 있을 때, 배열을 돌려보려고 한다. 배열은 다음과 같이 반시계 방향으로 돌려야 한다. A[1][1] ← A[1][2] ← A[1][3] ← A[1][4] ← A[1][5] ↓ ↑ A[2][1] A[2][2] ← A[2][3] ← A[2][4] A[2][5]

www.acmicpc.net

 

💡 풀이법

1. 회전 시킨 결과값을 저장할 2차원 행렬 new_matrix를 만들어주었다.

2. pointer를 이동시키는 move 함수를 만들었다. 만약 포인터를 현재 방향으로 이동시켰을때 인덱스를 넘어간다면 포인터를 다시 그 전으로 돌리고 방향을 바꿔준 후 포인터를 다시 이동시켜준다.

3. 먼저 횟수에 따라 배열을 돌리기 시작하는 첫 칸(x, y)이 어느 칸(nx, ny)에 가야하는지를 구하고 matrix[x][y]의 값을 new_matrix[nx][ny]에 넣어준다.

(x,y는 기존의 matrix의 pointer고, nx, ny는 new_matrix의 pointer이다.

4. matrix의 pointer(x, y)와 new_matrix의 pointer(nx, ny)를 move 함수를 통해 한칸씩 이동시키면서 계속해서 matrix[x][y]의 값을 new_matrix[nx][ny]에 넣어준다.

5. x, y가 첫 시작점이 되면 while문을 멈춘다.

6. 그 다음 회전시킬 구역의 시작점으로 x, y, nx, ny를 옮겨주고 다시 while문을 돌린다.

 

dx = [1,0,-1,0]
dy = [0,1,0,-1]

def move(x, y, i, n):
    x += dx[i]
    y += dy[i]
    if x < n or x >= N-n or y < n or y >= M-n:
        x -= dx[i]
        y -= dy[i]
        i = (i+1)%4
        x += dx[i]
        y += dy[i]        
    return x, y, i

def rotate(matrix):
    for n in range(min(N, M)//2):
        x = y = n
        nx = ny = n
        i = ni = 0
        for _ in range(R):
            nx, ny, ni = move(nx, ny, ni, n)

        new_matrix[nx][ny] = matrix[x][y]

        while True:
            x, y, i = move(x, y, i, n)
            nx, ny, ni = move(nx, ny, ni, n)
            if x == y == n:
                break
            new_matrix[nx][ny] = matrix[x][y]
        
N, M, R = map(int,input().split())
matrix = [list(map(int, input().split())) for _ in range(N)]
new_matrix = [[0 for _ in range(M)] for _ in range(N)]
rotate(matrix)
for i in range(N):
    print(*new_matrix[i])