백준 16926 - 배열 돌리기 1
Updated:
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번 회전시킨 결과를 구해보자.
접근 방법
주어진 연산에따라 배열의 값을 변화하였다.
4 X 4의 배열을 예로 들면,
[0,0] <- [0,1] / [0,1] <- [0,2] / [0,2] <- [0,3] : 우
[0,3] <- [1,3] / [1,3] <- [2,3] / [2,3] <- [3,3] : 하
[3,3] <- [3,2] / [3,2] <- [3,1] / [3,1] <- [3,0] : 좌
[3,0] <- [2,0] / [2,0] <- [1,0] / [1,0] <- [0,0] : 상
인 시계방향으로 값을 하나씩 차례로 대입시킨다.
또한 주목해야 할 것은, 문제 조건 중
min(N, M) mod 2 = 0이다.
이말은 즉, 행/열의 크기 중 작은 값은 항상 2의 배수라는 것이며, 위 조건이 있는 이유는
와 같이 3 x 4의 경우, 위 색칠 된 부분은 우하좌상의 방식으로 회전을 할 수 없다.
따라서 사전에 제약을 두어 위 경우는 생각하지 않아도 되게 하였다.
구현
전달 하려는 값을 시계방향으로 하나씩 이동하며 넣는다.
0,0을 미리 temp로 백업 시켜놓아, 마지막 대입인 [1,0] <- [0,0]를 가능하게 한다.
대입 하려는 값의 인덱스가 n X m의 범위를 벗어나면, 방향을 바꾸어 지속한다.
우 하 좌 상인 4 방향을 다 돌고 나면, 종료한다.
코드
import java.util.*;
import java.io.*;
public class Main {
static int dy[] = {0,1,0,-1}; // 우, 하, 좌, 상
static int dx[] = {1,0,-1,0};
public static void main(String []args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer stk = new StringTokenizer(br.readLine());
int n = stoi(stk.nextToken());
int m = stoi(stk.nextToken());
int r = stoi(stk.nextToken());
int arr[][] = new int[n][m];
int sm = Math.min(n, m);
for(int i = 0; i < n; i++) {
stk = new StringTokenizer(br.readLine());
for(int j = 0; j < m; j++)
arr[i][j] = stoi(stk.nextToken());
}
int i, j, d = 0;
while(r-- != 0) { // 반복 횟수만큼 움직인다.
for(int idx = 0; idx < sm/2; idx++) {
i = idx;
j = idx;
d = 0;
int tmp = arr[i][j];
while(d != 4) {
// 만약 범위를 벗어나면, 대입하는 값의 방향을 바꾼다.
if(i + dy[d] < idx || i + dy[d] >= n - idx || j + dx[d] < idx || j + dx[d] >= m - idx) {
d++;
continue;
}
arr[i][j] = arr[i + dy[d]][j + dx[d]];
i += dy[d];
j += dx[d];
}
arr[idx + 1][idx] = tmp;
}
}
StringBuilder sb = new StringBuilder();
for(int[] a : arr) {
for(int v : a) {
sb.append(v).append(" ");
}
sb.append("\n");
}
System.out.println(sb.toString());
br.close();
}
static int stoi(String str) {
return Integer.parseInt(str);
}
}
총평
난이도
⭐⭐★★★
후기
문제 조건인 행/열 최소 값은 2의 배수이다를 읽지 않아, 쓸데없이 고생했다.
문제를 잘 읽어라는 교수님 말씀이 뭔지 새삼 깨닫게된다 정말로,,
개선할 점
문제 좀 읽자!!!!