[백준, BOJ 16935] 배열 돌리기 3 (java)
Problem Solving/BOJ

[백준, BOJ 16935] 배열 돌리기 3 (java)

728x90

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번 적용하려고 한다. 연산은 총 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 → 7 4 6 2 3 1
7 4 6 2 3 1 → 1 8 3 4 2 9
9 2 3 6 1 5 → 7 2 6 9 8 2
4 2 9 3 1 8 → 1 6 2 9 8 4
   <배열>       <연산 결과>

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
   <배열>       <연산 결과>

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
   <배열>       <연산 결과>

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

5번 연산은 1번 그룹의 부분 배열을 2번 그룹 위치로, 2번을 3번으로, 3번을 4번으로, 4번을 1번으로 이동시키는 연산이다.

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
     <배열>            <연산 결과>

6번 연산은 1번 그룹의 부분 배열을 4번 그룹 위치로, 4번을 3번으로, 3번을 2번으로, 2번을 1번으로 이동시키는 연산이다.

3 2 6 3 1 2 9 7 → 1 2 9 7 6 3 9 2
9 7 8 2 1 4 5 3 → 1 4 5 3 7 9 2 1
5 9 2 1 9 6 1 8 → 9 6 1 8 8 2 1 3
2 1 3 8 6 3 9 2 → 3 2 6 3 2 1 3 8
1 3 2 8 7 9 2 1 → 9 7 8 2 1 3 2 8
4 5 1 9 8 2 1 3 → 5 9 2 1 4 5 1 9
     <배열>            <연산 결과>

입력

첫째 줄에 배열의 크기 N, M과 수행해야 하는 연산의 수 R이 주어진다.

둘째 줄부터 N개의 줄에 배열 A의 원소 $A_{ij}$가 주어진다.

마지막 줄에는 수행해야 하는 연산이 주어진다. 연산은 공백으로 구분되어져 있고, 문제에서 설명한 연산 번호이며, 순서대로 적용시켜야 한다.

출력

입력으로 주어진 배열에 R개의 연산을 순서대로 수행한 결과를 출력한다.

제한

  • 2 ≤ N, M ≤ 100
  • 1 ≤ R ≤ 1,000
  • N, M은 짝수
  • 1 ≤ $A_{ij}$ ≤ $10^8$
728x90

 

예제 입력 1

6 8 1
3 2 6 3 1 2 9 7
9 7 8 2 1 4 5 3
5 9 2 1 9 6 1 8
2 1 3 8 6 3 9 2
1 3 2 8 7 9 2 1
4 5 1 9 8 2 1 3
1

예제 출력 1

4 5 1 9 8 2 1 3
1 3 2 8 7 9 2 1
2 1 3 8 6 3 9 2
5 9 2 1 9 6 1 8
9 7 8 2 1 4 5 3
3 2 6 3 1 2 9 7

 

예제 입력 2

6 8 1
3 2 6 3 1 2 9 7
9 7 8 2 1 4 5 3
5 9 2 1 9 6 1 8
2 1 3 8 6 3 9 2
1 3 2 8 7 9 2 1
4 5 1 9 8 2 1 3
2

예제 출력 2

7 9 2 1 3 6 2 3
3 5 4 1 2 8 7 9
8 1 6 9 1 2 9 5
2 9 3 6 8 3 1 2
1 2 9 7 8 2 3 1
3 1 2 8 9 1 5 4

 

예제 입력 3

6 8 1
3 2 6 3 1 2 9 7
9 7 8 2 1 4 5 3
5 9 2 1 9 6 1 8
2 1 3 8 6 3 9 2
1 3 2 8 7 9 2 1
4 5 1 9 8 2 1 3
3

예제 출력 3

4 1 2 5 9 3
5 3 1 9 7 2
1 2 3 2 8 6
9 8 8 1 2 3
8 7 6 9 1 1
2 9 3 6 4 2
1 2 9 1 5 9
3 1 2 8 3 7

 

 

예제 입력 4

6 8 1
3 2 6 3 1 2 9 7
9 7 8 2 1 4 5 3
5 9 2 1 9 6 1 8
2 1 3 8 6 3 9 2
1 3 2 8 7 9 2 1
4 5 1 9 8 2 1 3
4

예제 출력 4

7 3 8 2 1 3
9 5 1 9 2 1
2 4 6 3 9 2
1 1 9 6 7 8
3 2 1 8 8 9
6 8 2 3 2 1
2 7 9 1 3 5
3 9 5 2 1 4

 

예제 입력 5

6 8 1
3 2 6 3 1 2 9 7
9 7 8 2 1 4 5 3
5 9 2 1 9 6 1 8
2 1 3 8 6 3 9 2
1 3 2 8 7 9 2 1
4 5 1 9 8 2 1 3
5

예제 출력 5

2 1 3 8 3 2 6 3
1 3 2 8 9 7 8 2
4 5 1 9 5 9 2 1
6 3 9 2 1 2 9 7
7 9 2 1 1 4 5 3
8 2 1 3 9 6 1 8

 

예제 입력 6

6 8 1
3 2 6 3 1 2 9 7
9 7 8 2 1 4 5 3
5 9 2 1 9 6 1 8
2 1 3 8 6 3 9 2
1 3 2 8 7 9 2 1
4 5 1 9 8 2 1 3
6

예제 출력 6

1 2 9 7 6 3 9 2
1 4 5 3 7 9 2 1
9 6 1 8 8 2 1 3
3 2 6 3 2 1 3 8
9 7 8 2 1 3 2 8
5 9 2 1 4 5 1 9

 

예제 입력 7

6 8 6
3 2 6 3 1 2 9 7
9 7 8 2 1 4 5 3
5 9 2 1 9 6 1 8
2 1 3 8 6 3 9 2
1 3 2 8 7 9 2 1
4 5 1 9 8 2 1 3
1 2 3 4 5 6

예제 출력 7

3 1 2 8 9 1 5 4
1 2 9 7 8 2 3 1
2 9 3 6 8 3 1 2
8 1 6 9 1 2 9 5
3 5 4 1 2 8 7 9
7 9 2 1 3 6 2 3

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
	
	static int N;
	static int M;
	static int[][] arr;
	
	static void turn(int c) {
		// 1번 연산
		if(c == 1) { // 상하 반전
			for (int i = 0; i < N / 2; i++) {
				int[] tmp = arr[i];
				arr[i] = arr[N - 1 - i];
				arr[N - 1 - i] = tmp;
			}
		}
		
		// 2번 연산
		else if(c == 2) { // 좌우 반전
			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 - 1 - j];
					arr[i][M - 1 - j] = tmp;
				}
			}
		}
		
		// 3번 연산
		else if(c == 3) {
			int[][] tmpArr = new int[M][N]; // 임시 배열
			for (int i = 0; i < N; i++) { // 오른쪽으로 회전
				for (int j = 0; j < M; j++) {
					tmpArr[j][N - 1 - i] = arr[i][j];
				}
			}
			int tmp = N; // 가로 세로 길이 바꿔주기
			N = M;
			M = tmp;
			arr = tmpArr;
		}
		
		// 4번 연산
		else if(c == 4) {
			int[][] tmpArr = new int[M][N]; // 임시 배열
			for (int i = 0; i < N; i++) { //왼쪽으로 회전
				for (int j = 0; j < tmpArr.length; j++) {
					tmpArr[M - 1 - j][i] = arr[i][j];
				}
			}
			int tmp = N; // 가로 세로 길이 바꿔주기
			N = M;
			M = tmp;
			arr = tmpArr;
		}
		
		// 5번 연산
		else if(c == 5) {
			int[][] tmpArr = new int[N][M]; // 임시 배열
			for (int i = 0; i < N / 2; i++) {
				for (int j = 0; j < M / 2; j++) { 
					tmpArr[i][M / 2 + j] = arr[i][j]; // 1번 그룹 -> 2번 그룹
					tmpArr[N / 2 + i][M / 2 + j] = arr[i][M / 2 + j]; // 2번 그룹 -> 3번 그룹
					tmpArr[N / 2 + i][j] = arr[N / 2 + i][M / 2 + j]; // 3번 그룹 -> 4번 그룹
					tmpArr[i][j] = arr[N / 2 + i][j]; // 4번 그룹 -> 1번 그룹
				}
			}
			arr = tmpArr;
		}
		
		// 6번 연산
		else {
			int[][] tmpArr = new int[N][M]; // 임시 배열
			for (int i = 0; i < N / 2; i++) {
				for (int j = 0; j < M / 2; j++) { 
					tmpArr[N / 2 + i][j] = arr[i][j]; // 1번 그룹 -> 4번 그룹
					tmpArr[N / 2 + i][M / 2 + j] = arr[N / 2 + i][j]; // 4번 그룹 -> 3번 그룹
					tmpArr[i][M / 2 + j] = arr[N / 2 + i][M / 2 + j]; // 3번 그룹 -> 2번 그룹
					tmpArr[i][j] = arr[i][M / 2 + j]; // 2번 그룹 -> 1번 그룹
				}
			}
			arr = tmpArr;
		}
	}

	public static void main(String[] args) throws Exception{
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		StringBuilder sb = new StringBuilder();
		
		// N, M, R 입력
		st = new StringTokenizer(br.readLine());
		N = Integer.parseInt(st.nextToken());
		M = Integer.parseInt(st.nextToken());
		int R = Integer.parseInt(st.nextToken());
		
		// 배열 입력
		arr = new int[N][M];
		for (int i = 0; i < N; i++) {
			st = new StringTokenizer(br.readLine());
			for (int j = 0; j < M; j++) {
				arr[i][j] = Integer.parseInt(st.nextToken());
			}
		}
		
		// 연산 번호 입력
		int[] r = new int[R];
		st = new StringTokenizer(br.readLine());
		for (int i = 0; i < R; i++) {
			r[i] = Integer.parseInt(st.nextToken());
		}

		// 연산 시작
		for (int i = 0; i < R; i++) {
			if(i + 1 < R && r[i] == 1 && r[i + 1] == 1) { // 1번 연산이 2번 연속으로 나오면 안하는 것과 똑같음
				i++;
			}
			else if(i + 1 < R && r[i] == 2 && r[i + 1] == 2) { // 2번 연산이 2번 연속으로 나오면 안하는 것과 똑같음
				i++;
			}
			else if(i + 1 < R && r[i] == 3 && r[i + 1] == 4) { // 3번 연산 다음 4번 연산 나오면 안하는 것과 똑같음
				i++;
			}
			else if(i + 1 < R && r[i] == 4 && r[i + 1] == 3) { // 4번 연산 다음 3번 연산 나오면 안하는 것과 똑같음
				i++;
			}
			else if(i + 1 < R && r[i] == 5 && r[i + 1] == 6) { // 5번 연산 다음 6번 연산 나오면 안하는 것과 똑같음
				i++;
			}
			else if(i + 1 < R && r[i] == 6 && r[i + 1] == 5) { // 6번 연산 다음 5번 연산 나오면 안하는 것과 똑같음
				i++;
			}
			else { // 위의 조건이 모두 해당되지 않을 때만 실행
				turn(r[i]);
			}
		}

		// 출력
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < M; j++) {
				sb.append(arr[i][j]);
				if(j != M - 1) sb.append(" ");
			}
			sb.append("\n");
		}
		System.out.println(sb);
	}
}
728x90