[백준/JAVA] 16935번: 배열 돌리기 3
📖 문제
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
💡 풀이 방식
• 구현
1,2번 연산
- 임시 배열에 [상하/좌우] 반전시킨 값을 저장하고, 그 배열의 값을 원본 배열로 복사해 저장한다.
3,4번 연산
- [열의 크기][행의 크기]를 갖는 2차원 임시 배열을 생성해 [오른쪽/왼쪽]으로 90도 회전시킨 값을 저장하고, 그 배열의 값을 원본 배열로 복사해 저장한다.
5번 연산
1. 원본 배열을 4등분한 구역에서 각각 임시 배열에 값을 저장한다. (행 길이 : r, 열 길이 : c)
[구역 1] x 범위 : [0, r/2) / y 범위 : [0, c/2]
[구역 2] x 범위 : [0, r/2) / y 범위 : [c/2, c)
[구역 3] x 범위 : [r/2, r) / y 범위 : [c/2, c)
[구역 4] x 범위 : [r/2, r) / y 범위 : [0, c/2]
g1 -> g2로 이동하려면 현재 열의 위치에서 (열의 길이/2)를 더한 위치로 이동한다.
g2 -> g3으로 이동하려면 현재 행의 위치에서 (행의 길이/2)를 더한 위치로 이동한다.
g3 -> g4로 이동하려면 현재 열의 위치에서 (열의 길이/2)를 뺀 위치로 이동한다.
g4 -> g1로 이동하려면 현재 행의 위치에서 (행의 길이/2)를 뺀 위치로 이동한다.
2. 임시 배열의 값을 원본 배열로 복사해 저장한다.
6번 연산
1. 5번 연산과 같은 범위로 원본 배열을 4등분한 구역에서 각각 임시 배열에 값을 저장한다. (행 길이 : r, 열 길이 : c)
g1 -> g4로 이동하려면 현재 행의 위치에서 (행의 길이/2)를 더한 위치로 이동한다.
g4 -> g3으로 이동하려면 현재 열의 위치에서 (열의 길이/2)를 더한 위치로 이동한다.
g3 -> g2로 이동하려면 현재 행의 위치에서 (행의 길이/2)를 뺀 위치로 이동한다.
g2 -> g1로 이동하려면 현재 열의 위치에서 (열의 길이/2)를 뺀 위치로 이동한다.
2. 임시 배열의 값을 원본 배열로 복사해 저장한다.
💥 유의사항
3-6번 연산을 하면서 배열의 행과 열의 크기가 바뀌는데 이를 조심해서 배열 크기를 선언해야 한다!
그렇지 않으면 ArrayIndexOutOfBounds가 발생한다. .(는 내 얘기다..)
🔺 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
import java.util.*;
import java.io.*;
public class Main {
static int N,M,R;
static int[][] map, tmp;
static int r,c;
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());
map = new int[N][M];
for(int i = 0 ; i < N ; i++) {
st = new StringTokenizer(br.readLine(), " ");
for(int j = 0 ; j < M ; j++)
map[i][j] = Integer.parseInt(st.nextToken());
}
st = new StringTokenizer(br.readLine(), " ");
for(int i = 0 ; i < R ; i++) {
int num = Integer.parseInt(st.nextToken());
r = map.length;
c = map[0].length;
if(num == 1) move1();
else if(num == 2) move2();
else if(num == 3) move3();
else if(num == 4) move4();
else if(num == 5) move5();
else if(num == 6) move6();
}
print();
}
// 1. 상하 반전
private static void move1() {
tmp = new int[r][c];
for(int i = 0 ; i < r ; i++)
for(int j = 0 ; j < c ; j++)
tmp[r - 1 - i][j] = map[i][j];
map = tmp.clone();
}
// 2. 좌우 반전
private static void move2() {
tmp = new int[r][c];
for(int i = 0 ; i < r ; i++)
for(int j = 0 ; j < c ; j++)
tmp[i][c - 1 - j] = map[i][j];
map = tmp.clone();
}
// 3. 오른쪽으로 90도 회전
private static void move3() {
tmp = new int[c][r];
for(int i = 0 ; i < r ; i++)
for(int j = 0 ; j < c ; j++)
tmp[j][r - 1 - i] = map[i][j];
map = tmp.clone();
}
// 4. 왼쪽으로 90도 회전
private static void move4() {
tmp = new int[c][r];
for(int i = 0 ; i < r ; i++)
for(int j = 0 ; j < c ; j++)
tmp[c - 1 - j][i] = map[i][j];
map = tmp.clone();
}
// 5. 시계 방향 회전
private static void move5() {
tmp = new int[r][c];
// g1 -> g2
for(int i = 0 ; i < r/2 ; i++) {
for(int j = 0 ; j < c/2 ; j++)
tmp[i][j + c/2] = map[i][j];
}
// g2 -> g3
for(int i = 0 ; i < r/2 ; i++) {
for(int j = c/2 ; j < c ; j++)
tmp[i + r/2][j] = map[i][j];
}
// g3 -> g4
for(int i = r/2 ; i < r ; i++) {
for(int j = c/2 ; j < c ; j++)
tmp[i][j - c/2] = map[i][j];
}
// g4 -> g1
for(int i = r/2 ; i < r ; i++) {
for(int j = 0 ; j < c/2 ; j++)
tmp[i - r/2][j] = map[i][j];
}
map = tmp.clone();
}
// 6. 반시계 방향 회전
private static void move6() {
tmp = new int[r][c];
// g1 -> g4
for(int i = 0 ; i < r/2 ; i++) {
for(int j = 0 ; j < c/2 ; j++)
tmp[i + r/2][j] = map[i][j];
}
// g2 -> g1
for(int i = 0 ; i < r/2 ; i++) {
for(int j = c/2 ; j < c ; j++)
tmp[i][j - c/2] = map[i][j];
}
// g3 -> g2
for(int i = r/2 ; i < r ; i++) {
for(int j = c/2 ; j < c ; j++)
tmp[i - r/2][j] = map[i][j];
}
// g4 -> g3
for(int i = r/2 ; i < r ; i++) {
for(int j = 0 ; j < c/2 ; j++)
tmp[i][j + c/2] = map[i][j];
}
map = tmp.clone();
}
private static void print() {
StringBuilder sb = new StringBuilder();
for(int[] i : map) {
for(int j : i) {
sb.append(j + " ");
}
sb.append("\n");
}
System.out.println(sb.toString());
}
}
|
cs |
➕ 다른 풀이 방식
3-6번 연산할 때 맨 마지막에 n과 m을 swap하셨고, 3-4번 연산에서 임시 배열 선언할 때 그냥 [m][n]으로 선언하셨다.
Baekjoon 16935 배열 돌리기 3 JAVA
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 →
hunucho.tistory.com
💦 어려웠던 점
- 1트 때 100분 걸리다가 절전 모드 했더니 날아가고 다시 풀었을 땐 60분 소요되었다
🧐 새로 알게 된 내용
- 매번 행과 열 크기 구해서 임시 배열 선언할 생각했었는데 그냥 swap 하고 선언은 [m][n]으로 진행해도 되었던 것이었다!
1회독 | 2회독 | 3회독 | 4회독 | 5회독 |
V |