YataNox
[Java] 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]
↓ ↓ ↑ ↑
A[3][1] A[3][2] → A[3][3] → A[3][4] A[3][5]
↓ ↑
A[4][1] → A[4][2] → A[4][3] → A[4][4] → A[4][5]
예를 들어, 아래와 같은 배열을 2번 회전시키면 다음과 같이 변하게 된다.
1 2 3 4 2 3 4 8 3 4 8 6
5 6 7 8 1 7 7 6 2 7 8 2
9 8 7 6 → 5 6 8 2 → 1 7 6 3
5 4 3 2 9 5 4 3 5 9 5 4
<시작> <회전1> <회전2>
배열과 정수 R이 주어졌을 때, 배열을 R번 회전시킨 결과를 구해보자.
문제 풀이
우선 배열을 받았을 때 돌려야할 그룹의 수가 몇 개인지가 중요하다.
입력받은 n,m 중 작은 값을 / 2 하면 그룹의 수가 나온다. = Math.min(n, m) / 2
다음으로 temp 배열을 만들 것이 아니라면 배열을 한 칸 돌릴 때 처음 시작 값을 빼놓았다가 돌리는 작업이 끝난 뒤 필요한 위치에 해당 값을 삽입해야한다.
더욱 자세한 로직은 주석으로 남긴다.
자바 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class N16926 {
private static int n, m, r;
private static int group;
private static int[][] arr;
private static final int[] dr = {0, 1, 0, -1};
private static final int[] dc = {1, 0, -1, 0};
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
r = Integer.parseInt(st.nextToken());
arr = new int[n][m];
// 그룹의 수, n과 m중 작은 쪽의 나누기 2 한 값이 그룹의 수가 된다.
group = Math.min(n,m) / 2;
for(int i = 0; i < arr.length; i++){
st = new StringTokenizer(br.readLine(), " ");
for(int j = 0; j < arr[i].length; j++){
arr[i][j] = Integer.parseInt(st.nextToken());
}
}
// 회전 수 만큼 실행
for(int i = 0; i < r; i++)
rotate();
// 출력
for(int[] arrA : arr){
for(int i : arrA){
System.out.print(i + " ");
}
System.out.println();
}
}
public static void rotate(){
int x, y, idx;
// 그룹 수 만큼 실행한다.
for(int i = 0; i < group; i++){
// 그룹 시작 인덱스 x, y
// 1그룹이면 0,0 2그룹이면 1,1 등으로 시작한다.
x = i;
y = i;
// 처음의 인덱스 값을 미리 빼놓는다.
// 맨 마지막에 i+1, i 인덱스 위치에 삽입해준다.
int temp = arr[x][y];
// 방향 초기화
idx = 0;
// 4방향을 다 돌때까지 진행한다.
// dr, dc에 따라서 우,하,좌,상 방향으로 탐색한다.
while(idx < 4){
// 현재 위치에서 우,하,좌,상 방향의 인덱스 위치를 얻는다.
int nx = x + dr[idx];
int ny = y + dc[idx];
// 해당 인덱스 위치가 그룹의 범위를 벗어나지 않는 경우에 현 (x,y)에 (nx,ny)값을 넣어준다.
// 예를 들자면 맨처음 0,0에서 시작하여 오른쪽 값(0,1 .... 0,m)을 확인하면서 넣어줄 것이다.
// 그러다가 오른쪽 범위를 벗어나면 (0, m+1) 그때부터는 idx를 1 올려주어 아랫쪽으로 이동하는 것. (1, m)
if(nx < n - i && ny < m - i && nx >= i && ny >= i){
arr[x][y] = arr[nx][ny];
x = nx;
y = ny;
}else{
idx++;
}
}
// 마지막으로 처음 빼놓았던 i,i 인덱스 위치의 값을 삽입한다.
arr[i + 1][i] = temp;
}
}
}
'코딩 테스트 > BAEKJOON' 카테고리의 다른 글
[Java] 15558 점프 게임 (0) | 2024.05.14 |
---|---|
[Java] 16927 배열 돌리기 2 (0) | 2024.05.09 |
[Java] 2290 LCD Test (0) | 2024.05.09 |
[Java] 16931 겉넓이 구하기 (0) | 2024.05.08 |
[Java] 16967 배열 복원하기 (0) | 2024.05.07 |