728x90
1. 문제
https://www.acmicpc.net/problem/16935
16935번: 배열 돌리기 3
크기가 N×M인 배열이 있을 때, 배열에 연산을 R번 적용하려고 한다. 연산은 총 6가지가 있다. 1번 연산은 배열을 상하 반전시키는 연산이다. 1 6 2 9 8 4 → 4 2 9 3 1 8 7 2 6 9 8 2 → 9 2 3 6 1 5 1 8 3 4 2 9 →
www.acmicpc.net
배열의 크기는 N*M이다. 주어진 R개의 연산을 순서대로 적용시킨 후 결과를 출력해야한다.
1번 연산 : 상하반전
2번 연산 : 좌우반전
3번 연산 : 오른쪽 90도 회전
4번 연산 : 왼쪽 90도 회전
5번 연산 : 4개의 부분배열로 나눠 그룹의 순서를 시계방향으로 이동
6번 연산 : 4개의 부분배열로 나눠 그룹의 순서를 반시계방향으로 이동
2. 풀이
상하함수
줄단위로 바꾼다.
private static void moveUD() {
for (int i = 0; i < N / 2; i++) {
int[] tmp = arr[i];
arr[i] = arr[N - i - 1];
arr[N - i - 1] = tmp;
}
}
좌우함수
하나하나 바꿔준다.
private static void moveLR() {
for (int i = 0; i < N; i++) {
for (int j = 0; j < M / 2; j++) {
int tmp = arr[i][j];
arr[i][j] = arr[i][M - j - 1];
arr[i][M - j - 1] = tmp;
}
}
}
90도 회전 함수
- isRight변수로 오른쪽 회전(true)인지 왼쪽 회전(false)인지 체크한다.
- 90도 회전이기때문에 가로와 세로길이가 변경된다. 따라서 새 M*N배열(tmp)을 만든다.
- 오른쪽회전이라면 tmp[j][N-i-1]에, 왼쪽회전이라면 tmp[M-j-1][i]에 저장한다.
- 마지막으로 static arr, M,N을 현재 값으로 바꿔준다.
private static void turn(boolean isRight) {
int tmp[][] = new int[M][N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if(isRight) tmp[j][N-i-1] = arr[i][j];
else tmp[M-j-1][i] = arr[i][j];
}
}
arr = tmp;
int num = M;
M = N;
N = num;
}
부분배열 회전 함수
- 방향에 따라서 부분배열시작점과 이동값을 순서대로 초기화한다.
- ex) 시계방향은 처음 (0,0)에서 시작한 배열이 오른쪽으로 이동하므로 (0,halfN) 저장
- 시계방향 : 오른쪽-아래-왼쪽-위
- 반시계방향 : 아래-왼쪽-위-오른쪽
private static void divide(boolean isRight) {
int[][] tmp = new int[N][M];
int[][] deltas;
int halfN = N/2;
int halfM = M/2;
if(isRight){
divideIdx = new int[][]{{0, 0}, {0, halfM}, {halfN, halfM}, {halfN, 0}};
deltas = new int[][]{{0, halfM}, {halfN, 0}, {0, -halfM}, {-halfN, 0}};
}else {
divideIdx = new int[][]{{0, 0}, {halfN, 0}, {halfN, halfM}, {0, halfM}};
deltas = new int[][]{{halfN, 0}, {0, halfM}, {-halfN, 0}, {0, -halfM}};
}
for(int k=0;k<4;k++){
for (int i = divideIdx[k][0]; i < divideIdx[k][0]+N/2; i++) {
for (int j = divideIdx[k][1]; j < divideIdx[k][1]+M/2; j++) {
tmp[i+deltas[k][0]][j+deltas[k][1]] = arr[i][j];
}
}
}
arr = tmp;
}
메인함수
- swtich case로 명령을 받을 때마다 회전시킨다.
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(in.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
R = Integer.parseInt(st.nextToken());
arr = new int[N][M];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(in.readLine());
for (int j = 0; j < M; j++) {
arr[i][j] = Integer.parseInt(st.nextToken());
}
}
st = new StringTokenizer(in.readLine());
for (int r = 0; r < R; r++) {
switch (st.nextToken().charAt(0)) {
case '1':
moveUD();
break;
case '2':
moveLR();
break;
case '3':
turn(true);
break;
case '4':
turn(false);
break;
case '5':
divide(true);
break;
case '6':
divide(false);
break;
}
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
sb.append(arr[i][j]).append(" ");
}
sb.append("\n");
}
System.out.print(sb);
}
3. 결과
'코딩테스트 > BOJ' 카테고리의 다른 글
[BOJ] 2491 수열 - JAVA (0) | 2022.02.12 |
---|---|
[BOJ] 17406 배열돌리기 4 - JAVA (0) | 2022.02.12 |
[BOJ] 16926 배열돌리기1 - JAVA (0) | 2022.02.12 |
[BOJ] 2563 색종이 - JAVA (0) | 2022.02.11 |
[BOJ] 2564 경비원 - JAVA (0) | 2022.02.11 |
댓글