문제 설명
크기가 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° 돌렸을 때의 결과가 우측 그리고 좌측에 있다. 굵은 원소는 주 대각선 / 중간 열 / 부 대각선 / 중간 행에 위치한 원소이다.
입력으로 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개의 정수를 공백으로 구분하여 출력한다.
🧐 어떻게 풀까
문제에 이동되는 블록의 좌표와 어떻게 이동하면 될지 자세하게 나와있어서 그대로 구현하면 되겠다고 생각했다.
구현 문제는 문제를 꼼꼼히 읽고 최대한 그대로 따라하도록 하는 것이 좋은 것 같다.
코드
- 시계방향으로만 생각한다. 음수 값(반시계 방향)이 들어올 경우 360도에서 빼준다.
- 입력받은 각도를 45도로 나눠 몇 번(n) 회전시켜야하는 알아낸다.
- 구현한 rotation 함수를 이용하여 n 번 회전 시킨다.
- 이동시켜야할 좌표들(대각선, 가운데 행열)을 이동시켜 newMap 배열에 저장한다.
- newMap을 참고하여 값이 변한 값을 기존 map 배열에 복사한다.
import java.io.*;
import java.io.BufferedReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int T = Integer.parseInt(br.readLine());
for(int t= 0; t<T; t++){
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int d = Integer.parseInt(st.nextToken());
// 음수이면 360도에서 빼기
d = (d <0)? 360+d : d;
int [][] map = new int[N][N];
for(int i=0; i<N; i++){
st = new StringTokenizer(br.readLine());
for(int j=0; j<N; j++){
map[i][j] = Integer.parseInt(st.nextToken());
}
}
int count = d/45;
int [][] result = rotation(map, count);
for(int i=0; i<N; i++){
for(int j=0; j<N; j++){
bw.write(map[i][j] +" ");
}
bw.write("\n");
}
}
bw.flush();
}
public static int[][] rotation(int [][] map, int count){
int length = map.length;
for(int r=0; r<count; r++){
int [][] newMap = new int[length][length];
// 1. 주 대각선 회전
for(int i=0; i<length; i++){
newMap[i][length/2] = map[i][i];
}
// 2. 가운데 열 회전
for(int i=0; i<length; i++){
newMap[i][length-1-i] = map[i][length/2];
}
// 3. 부대각선 옮기기
for(int i=0; i<length; i++){
newMap[length/2][length-1-i] = map[i][length-1-i];
}
// 4. 가운데 행 옮기기
for(int i=0; i<length; i++){
newMap[i][i] = map[length/2][i];
}
// 5. 나머지 원소 옮기기
for(int i=0; i<length; i++){
for(int j=0; j<length; j++){
if(newMap[i][j] != 0)
map[i][j] = newMap[i][j];
}
}
}
return map;
}
}
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 탑 - 2493 : JAVA (0) | 2024.02.27 |
---|---|
[백준] 달력 : 20207 - JAVA (0) | 2024.02.20 |
[백준] 빗물 - 14719 : Java (0) | 2024.02.20 |
[백준] RGB거리 :1149 -Java (0) | 2024.02.17 |
[백준] 불우이웃돕기 : 1414 - Java (0) | 2024.02.12 |