크기가 N x M 인 배열 - A[i][j]
배열돌리기 연산을 구현하는 문제
연산을 R번 수행한 결과 값을 구하는 문제
연산을 적용한 배열을 B[i][j]
B[i][j] -> A[?][?]
열을 보면 열의 위치는 고정
9 2 3 6 1 5 -> 9 2 3 6 1 5
행을 보면 행은 서로 반대된다. -> B의 0번행은 A의 N-1행
-> B의 1번행은 A의 N-2행
8 1
8 1
2 3
3 -> 2
1 8
1 8
B[i][j] -> A[N-i-1][j]
2.배열을 좌우 반전시키는 연산
1 6 2 9 8 4 → 4 8 9 2 6 1
7 2 6 9 8 2 → 2 8 9 6 2 7
1 8 3 4 2 9 → 9 2 4 3 8 1
7 4 6 2 3 1 → 1 3 2 6 4 7
9 2 3 6 1 5 → 5 1 6 3 2 9
4 2 9 3 1 8 → 8 1 3 9 2 4
<배열> <연산 결과>
열이 반전
행은 고정
B[i][j] -> A[i][M-j-1]
3.오른쪽으로 90도 회전시키는 연산
1 6 2 9 8 4 → 4 9 7 1 7 1
7 2 6 9 8 2 → 2 2 4 8 2 6
1 8 3 4 2 9 → 9 3 6 3 6 2
7 4 6 2 3 1 → 3 6 2 4 9 9
9 2 3 6 1 5 → 1 1 3 2 8 8
4 2 9 3 1 8 → 8 5 1 9 2 4
<배열> <연산 결과>
B[i][j] -> A[?][?]
행을 먼저 살펴보면 i번 행 -> i번열
B[i][j] -> A[?][i]
그러면 i가 고정되어 있을때
j번 열은???
B의 j번 열은 A의 N-j-1행
j가 반대로 감소해야함
열 j는 반대로 위치해야한다.
B의 j
B[i][j] -> A[N-j-1][i]
4.왼쪽으로 90도 회전시키는 연산
1 6 2 9 8 4 → 4 2 9 1 5 8
7 2 6 9 8 2 → 8 8 2 3 1 1
1 8 3 4 2 9 → 9 9 4 2 6 3
7 4 6 2 3 1 → 2 6 3 6 3 9
9 2 3 6 1 5 → 6 2 8 4 2 2
4 2 9 3 1 8 → 1 7 1 7 9 4
<배열> <연산 결과>
B[i][j] -> A[?][?]
행을 먼저 살펴보면 B의 i번 행은 A의 M-i-1 열
B[i][j] -> A[][M-i-1]
B의 j번 열 -> A의 j번 행
B[i][j] -> A[j][M-i-1]
5, 6번 연산을 수행하려면 배열을 크기가 N/2×M/2인 4개의 부분 배열로 나눠야 한다. 아래 그림은 크기가 6×8인 배열을 4개의 그룹으로 나눈 것이고, 1부터 4까지의 수로 나타냈다.
1 1 1 1//2 2 2 2
1 1 1 1//2 2 2 2
1 1 1 1//2 2 2 2
//////////////////
4 4 4 4//3 3 3 3
4 4 4 4//3 3 3 3
4 4 4 4//3 3 3 3
1번칸 범위 i<N/2, j<M/2
2번칸 범위 i<N/2, j>=M/2
3번칸 범위 i>=N/2, j<M/2
4번칸 범위 i>=N/2, j>=M/2
3 2 6 3 // 1 2 9 7 → 2 1 3 8 // 3 2 6 3
9 7 8 2 // 1 4 5 3 → 1 3 2 8 // 9 7 8 2
5 9 2 1 // 9 6 1 8 → 4 5 1 9 // 5 9 2 1
////////////////////// ////////////////////////
2 1 3 8 // 6 3 9 2 → 6 3 9 2 // 1 2 9 7
1 3 2 8 // 7 9 2 1 → 7 9 2 1 // 1 4 5 3
4 5 1 9 // 8 2 1 3 → 8 2 1 3 // 9 6 1 8
<배열> <연산 결과>
1번 그룹 (i,j)가 2번,3번,4번 그룹에서 어디에 해당하는지 봐야한다.
1번 그룹 (i,j)
-> 2번 (i,j+M/2)
-> 3번 (i+N/2,j+M/2)
-> 4번 (i+N/2,j)
import java.util.*;
public class Main {
static int[][] operation1(int[][] a) {
int n = a.length;
int m = a[0].length;
int[][] ans = new int[n][m];
for (int i=0; i<n; i++) {
for (int j=0; j<m; j++) {
ans[i][j] = a[n-i-1][j];
}
}
return ans;
}
static int[][] operation2(int[][] a) {
int n = a.length;
int m = a[0].length;
int[][] ans = new int[n][m];;
for (int i=0; i<n; i++) {
for (int j=0; j<m; j++) {
ans[i][j] = a[i][m-j-1];
}
}
return ans;
}
static int[][] operation3(int[][] a) {
int n = a.length;
int m = a[0].length;
int[][] ans = new int[m][n];;
for (int i=0; i<m; i++) {
for (int j=0; j<n; j++) {
ans[i][j] = a[n-j-1][i];
}
}
return ans;
}
static int[][] operation4(int[][] a) {
int n = a.length;
int m = a[0].length;
int[][] ans = new int[m][n];;
for (int i=0; i<m; i++) {
for (int j=0; j<n; j++) {
ans[i][j] = a[j][m-i-1];
}
}
return ans;
}
static int[][] operation5(int[][] a) {
int n = a.length;
int m = a[0].length;
int[][] ans = new int[n][m];
;
for (int i = 0; i < n / 2; i++) {
for (int j = 0; j < m / 2; j++) {
// 1번칸 -> 2번칸
ans[i][j + m / 2] = a[i][j];
// 2번칸 -> 3번칸
ans[i + n / 2][j + m / 2] = a[i][j + m / 2];
// 3번칸 -> 4번칸
ans[i + n / 2][j] = a[i + n / 2][j + m / 2];
// 4번칸 -> 1번칸
ans[i][j] = a[i + n / 2][j];
}
}
return ans;
}
static int[][] operation6(int[][] a) {
int n = a.length;
int m = a[0].length;
int[][] ans = new int[n][m];;
for (int i=0; i<n/2; i++) {
for (int j=0; j<m/2; j++) {
ans[i+n/2][j] = a[i][j];
ans[i][j] = a[i][j+m/2];
ans[i][j+m/2] = a[i+n/2][j+m/2];
ans[i+n/2][j+m/2] = a[i+n/2][j];
}
}
return ans;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int r = sc.nextInt();
int[][] a = new int[n][m];
for (int i=0; i<n; i++) {
for (int j=0; j<m; j++) {
a[i][j] = sc.nextInt();
}
}
while (r-- > 0) {
int op = sc.nextInt();
if (op == 1) {
a = operation1(a);
} else if (op == 2) {
a = operation2(a);
} else if (op == 3) {
a = operation3(a);
} else if (op == 4) {
a = operation4(a);
} else if (op == 5) {
a = operation5(a);
} else if (op == 6) {
a = operation6(a);
}
}
for (int i=0; i<a.length; i++) {
for (int j=0; j<a[i].length; j++) {
System.out.print(a[i][j] + " ");
}
System.out.println();
}
}
}