[Algorithm/Java] 백준 17276번 - 배열 돌리기
https://www.acmicpc.net/problem/17276
🔍 문제 풀이
풀이
N x N 크기의 2차원 배열이 주어졌을 때, 배열을 45도 단위로 시계 또는 반시계 방향으로 회전하는 문제이다.
- d값이 음수면
+360
으로 보정하여 시계 방향 회전으로 통일한다. d / 45
를 통해 회전 횟수를 계산한다.- 각 회전마다 대각선과 중앙 행·열을 따라 원소들을 이동시킨다.
- arr -> copy -> 다시 arr로 값들을 덮어쓰며 다음 회전을 준비한다.
느낀 점
① 회전 방향 통일
처음엔 시계 방향과 반시계 방향을 따로 구현해야 한다고 생각했지만,
반시계 방향도 +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];
}
}
}
}
댓글남기기