2 분 소요



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



🔍 문제 풀이

풀이

N x N 크기의 2차원 배열이 주어졌을 때, 배열을 45도 단위로 시계 또는 반시계 방향으로 회전하는 문제이다.

  1. d값이 음수면 +360으로 보정하여 시계 방향 회전으로 통일한다.
  2. d / 45를 통해 회전 횟수를 계산한다.
  3. 각 회전마다 대각선과 중앙 행·열을 따라 원소들을 이동시킨다.
  4. arr -> copy -> 다시 arr로 값들을 덮어쓰며 다음 회전을 준비한다.

17276 배열 돌리기


느낀 점

① 회전 방향 통일

처음엔 시계 방향과 반시계 방향을 따로 구현해야 한다고 생각했지만,
반시계 방향도 +360으로 보정하면 시계 방향 회전으로 통일할 수 있어 더 간단하게 해결할 수 있었다.


② 반복문 최소화

빙고 문제처럼 j까지 이중 반복문으로 순회해야 할 줄 알았는데,
이 문제에서 회전 대상은 전체가 아니라 정해진 축(십자 모양)만 회전하니까
i 하나만 써서 그 위치들을 바꾸면 되기 때문에 이중 반복문이 필요 없다는 것을 알게되었다.


배열 전체를 돌리는 것이 아니면 단일 반복문으로 충분하다!


③ 배열 갱신에 대한 오해

처음에는 복제 배열에 회전 결과만 저장하고 출력하면 끝이라고 생각했다.

그런데 회전을 여러 번 할 때 결과가 계속 이상하게 나와서 보니,
이전 회전 결과가 다음 회전에 반영되지 않고 있었던 거였다.

회전이 한 번만이라면 복제 배열만 써도 문제가 없지만,
이 문제처럼 회전을 여러 번 반복한다면 이전 회전 결과를 기준으로 다음 회전이 가능해야 하므로,
결과 배열을 다시 원본 배열에 반영해야 한다는 걸 알게 되었다.

앞으로는 복제 배열을 다룰 때 “이걸 다음에도 쓸 건가?” 부터 먼저 생각하자.


  • 해결 방법
    • 회전 전마다 arr -> copyArr 복사 (내가 사용한 방법)
    • 또는, rotate()가 새 배열 만들어서 arr = rotate(arr)로 덮어쓰기



💻 전체 코드

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

public class Main {
    static int arr[][];
    static int copy[][];

    static int n, d;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int t = Integer.parseInt(br.readLine());
        StringBuilder sb = new StringBuilder();

        while(t --> 0){
            // 입력
            StringTokenizer st = new StringTokenizer(br.readLine());
            n = Integer.parseInt(st.nextToken()); // 배열의 크기
            d = Integer.parseInt(st.nextToken()); // 각도

            arr = new int[n][n];
            copy = 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());
                    copy[i][j] = arr[i][j]; // 배열 복사
                }
            }

            // 각도 조정
            if(d < 0) d += 360; // 음수(반시계 회전)를 시계방향으로 변환 (예: -45 → 315)
            // if(d >= 360) d -= 360; // 360도 이상은 한 바퀴 회전과 동일하므로 생략 가능 (예: 405 → 45)

            // 회전 횟수 계산
            int cnt = d/45;

            // 45도 단위로 cnt번 회전 수행
            while(cnt --> 0){
                rotate();
            }

            // 출력
            for(int i=0; i<n; i++){
                for(int j=0; j<n; j++){
                    sb.append(arr[i][j]).append(" ");
                }
                sb.append("\n");
            }
        }
        System.out.println(sb);
    }

    // 45도 회전
    static void rotate(){
        int mid = n / 2;

        for (int i = 0; i < n; i++) {
            copy[i][i] = arr[mid][i]; // ㄱ
            copy[i][mid] = arr[i][i]; // ㄴ
            copy[i][n - 1 - i] = arr[i][mid]; // ㄷ
            copy[mid][n - 1 - i] = arr[i][n - 1 - i]; // ㄹ
        }

        // 원본 배열에 반영 (주의!!)
        for(int i=0; i<n; i++){
            for(int j=0; j<n; j++){
                arr[i][j] = copy[i][j];
            }
        }

    }
}


카테고리:

업데이트:

댓글남기기