백준 17276번 : 배열 돌리기

알고리즘Java코딩 테스트백준
avatar
2025.06.10
·
14 min read

문제

크기가 n x n인 2차원 정수 배열 X가 있다. (n은 홀수)

X를 45° 의 배수만큼 시계방향 혹은 반시계방향으로 돌리려고 한다. X를 시계 방향으로 45° 돌리면 아래와 같은 연산이 동시에 X에 적용되어야 한다:

  • X의 주 대각선을 ((1,1), (2,2), …, (n, n)) 가운데 열 ((n+1)/2 번째 열)로 옮긴다.

  • X의 가운데 열을 X의 부 대각선으로 ((n, 1), (n-1, 2), …, (1, n)) 옮긴다. 

  • X의 부 대각선을 X의 가운데 행 ((n+1)/2번째 행)으로 옮긴다.

  • X의 가운데 행을 X의 주 대각선으로 옮긴다.

  • 위 네 가지 경우 모두 원소의 기존 순서는 유지 되어야 한다.

  • X의 다른 원소의 위치는 변하지 않는다.

반시계 방향으로 45° 돌리는 경우도 위와 비슷하게 정의된다.

예를 들어, 아래 그림 중앙에 5x5 배열 X가 있고, 이 배열을 시계방향 혹은 반시계방향으로 45° 돌렸을 때의 결과가 우측 그리고 좌측에 있다. 굵은 원소는 주 대각선 / 중간 열 / 부 대각선 / 중간 행에 위치한 원소이다.

3

2

5

4

15

6

8

9

14

10

1

7

13

19

25

16

12

17

18

20

11

22

21

24

23

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

11

2

1

4

3

6

12

7

8

10

21

17

13

9

5

16

18

19

14

20

23

22

25

24

15

X를 반시계 방향으로 45° 회전한 경우

배열 X (5x5)

X를 시계 방향으로 45° 회전한 경우

입력으로 2차원 배열 X와 어느 방향으로 몇 도 회전할지 입력 받아, 그 결과를 출력하는 프로그램을 작성하시오.

입력

첫 줄에 테스트 케이스의 수 T가 주어진다 (1 ≤ T ≤ 10).

각 테스트 케이스에 대해: 첫 줄에 배열의 크기를 나타내는 n (1 ≤ n < 500, n은 홀수) 그리고 각도 d가 주어진다. d는 0 ≤ |d| ≤ 360 을 만족하며 |d| 는 45의 배수이다. d가 양수이면 시계방향으로 d° 돌려야 하고, 음수이면 반시계방향으로 |d|° 돌려야 한다. 다음 n줄에 걸쳐 각 줄에 n개의 정수가 공백으로 구분되어 주어진다 (X의 원소들을 나타낸다). 각 값은 1 이상 1,000,000 이하의 정수이다.

출력

각 테스트 케이스에 대해 회전 연산을 마친 후 배열의 상태를 출력한다. n줄에 걸쳐 각 줄에 n개의 정수를 공백으로 구분하여 출력한다. 


나의 풀이

  • 몇번 회전해야하는지 계산 (모두 시계 방향 회전 기준으로 통합)

    • ex) -45는 315로 치환하여 계산

  • 원본 배열 복사 후 4개의 축(가운데 행, 가운데 열, 주 대각선, 부 대각선)만 이동 (나머지는 유지)

나의 코드

import java.io.*;
import java.util.*;

/**
 * 백준 17276 - 배열 돌리기 (실버 2)
 * <a href="https://www.acmicpc.net/problem/17276">...</a>
 */
public class Main {

    private static final int DEFAULT_ANGLE = 45;

    private static int calculateTimes(int angle) {
        int normalized = ((angle % 360) + 360) % 360;
        return normalized / DEFAULT_ANGLE;
    }

    private static int[][] turn(int n, int[][] originArr, int times) {

        int[][] arr = originArr;

        for (int t = 0; t < times; t++) {
            int[][] newArr = new int[n][n];

            for (int i = 0; i < n; i++) {
                newArr[i] = Arrays.copyOf(arr[i], n);
            }

            int mid = n / 2;

            for (int i = 0; i < n; i++) {
                newArr[i][i] = arr[mid][i];
                newArr[i][mid] = arr[i][i];
                newArr[i][n - 1 -i] = arr[i][mid];
                newArr[mid][i] = arr[n - 1 - i][i];
            }

            arr = newArr;
        }

        return arr;
    }


    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        int T = Integer.parseInt(br.readLine());
        for (int k = 0; k < T; k++) {
            st = new StringTokenizer(br.readLine());
            int n = Integer.parseInt(st.nextToken());
            int d = Integer.parseInt(st.nextToken());

            int[][] arr = new int[n][n];

            for (int i = 0; i < n; i++) {
                st = new StringTokenizer(br.readLine());
                for (int j = 0; j < n; j++) {
                    arr[i][j] = Integer.parseInt(st.nextToken());
                }
            }

            int times = calculateTimes(d);
            int[][] answer = turn(n, arr, times);

            for (int[] row : answer) {
                for (int num : row) {
                    System.out.print(num + " ");
                }
                System.out.println();
            }
        }
    }
}






- 컬렉션 아티클