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번 연산은 배열을 상하 반전시키는 연산이다.

2번 연산은 배열을 좌우 반전시키는 연산이다.

3번 연산은 오른쪽으로 90도 회전시키는 연산이다.

4번 연산은 왼쪽으로 90도 회전시키는 연산이다.

5, 6번 연산을 수행하려면 배열을 크기가 N/2×M/2인 4개의 부분 배열로 나눠야 한다. 아래 그림은 크기가 6×8인 배열을 4개의 그룹으로 나눈 것이고, 1부터 4까지의 수로 나타냈다.

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

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

입력

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

둘째 줄부터 N개의 줄에 배열 A의 원소 Aij가 주어진다.

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

출력

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

제한

  • 2 ≤ N, M ≤ 100
  • 1 ≤ R ≤ 1,000
  • N, M은 짝수
  • 1 ≤ Aij ≤ 108

 

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

public class Main {
	static int[][] arr;

	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");

		int N = Integer.parseInt(st.nextToken());
		int M = Integer.parseInt(st.nextToken());
		int R = Integer.parseInt(st.nextToken());

		// 배열 입력
		arr = new int[N][M];
		for (int n = 0; n < N; n++) {
			st = new StringTokenizer(br.readLine());
			for (int m = 0; m < M; m++) {
				arr[n][m] = Integer.parseInt(st.nextToken());
			}
		}
		
		st = new StringTokenizer(br.readLine());
		for (int i = 0; i < R; i++) {
			switch (Integer.parseInt(st.nextToken())) {
			case 1:
				oper_1();
				break;
			case 2:
				oper_2();
				break;
			case 3:
				oper_3();
				break;
			case 4:
				oper_4();
				break;
			case 5:
				oper_5();
				break;
			case 6:
				oper_6();
				break;
			}
		}
		for (int n = 0; n < arr.length; n++) {
			for (int m = 0; m < arr[0].length; m++) {
				if (m == arr[0].length - 1)
					System.out.print(arr[n][m]);
				else
					System.out.print(arr[n][m] + " ");
			}
			if (n != arr.length - 1)
				System.out.println();
		}

	}

	static void oper_1() {
		int temp;
		for (int n = 0; n < arr.length / 2; n++) {
			for (int j = 0; j < arr[0].length; j++) {
				temp = arr[n][j];
				arr[n][j] = arr[arr.length - 1 - n][j];
				arr[arr.length - 1 - n][j] = temp;
			}
		}
	}

	static void oper_2() {
		int temp;
		for (int n = 0; n < arr.length; n++) {
			for (int j = 0; j < arr[0].length / 2; j++) {
				temp = arr[n][j];
				arr[n][j] = arr[n][arr[0].length - 1 - j];
				arr[n][arr[0].length - 1 - j] = temp;
			}
		}
	}

	static void oper_3() {
		int[][] arr_3 = new int[arr[0].length][arr.length];

		for (int i = 0; i < arr[0].length; i++) {
			for (int j = 0; j < arr.length; j++) {
				arr_3[i][j] = arr[arr.length - 1 - j][i];
			}
		}

		arr = new int[arr[0].length][arr.length];
		for (int i = 0; i < arr_3.length; i++) {
			for (int j = 0; j < arr_3[0].length; j++) {
				arr[i][j] = arr_3[i][j];
			}
		}
	}

	static void oper_4() {
		int[][] arr_3 = new int[arr[0].length][arr.length];

		for (int i = 0; i < arr[0].length; i++) {
			for (int j = 0; j < arr.length; j++) {
				arr_3[i][j] = arr[j][arr[0].length - 1 - i];
			}
		}

		arr = new int[arr[0].length][arr.length];
		for (int i = 0; i < arr_3.length; i++) {
			for (int j = 0; j < arr_3[0].length; j++) {
				arr[i][j] = arr_3[i][j];
			}
		}
	}

	static void oper_5() {
		int[][] temp = new int[arr.length/2][arr[0].length/2];
		// 1번 부분 배열 temp에 저장
		for (int i = 0; i < arr.length/2; i++) {
			for (int j = 0; j < arr[0].length/2; j++) {
				temp[i][j] = arr[i][j];
			}
		}
		// 4->1
		for (int i = 0; i < arr.length/2; i++) {
			for (int j = 0; j < arr[0].length/2; j++) {
				arr[i][j] = arr[arr.length/2 + i][j];
			}
		}
		// 3->4
		for (int i = arr.length/2; i < arr.length; i++) {
			for (int j = 0; j < arr[0].length/2; j++) {
				arr[i][j] = arr[i][arr[0].length/2+j];
			}
		}
		// 2->3
		for (int i = arr.length/2; i < arr.length; i++) {
			for (int j = arr[0].length/2; j < arr[0].length; j++) {
				arr[i][j] = arr[i-arr.length/2][j];
			}
		}
		// 1->2
		for (int i = 0; i < arr.length/2; i++) {
			for (int j = arr[0].length/2; j < arr[0].length; j++) {
				arr[i][j] = temp[i][j-arr[0].length/2];
			}
		}
	}

	static void oper_6() {
		int[][] temp = new int[arr.length/2][arr[0].length/2];
		// 1번 부분 배열 temp에 저장
		for (int i = 0; i < arr.length/2; i++) {
			for (int j = 0; j < arr[0].length/2; j++) {
				temp[i][j] = arr[i][j];
			}
		}
		// 2->1
		for (int i = 0; i < arr.length/2; i++) {
			for (int j = 0; j < arr[0].length/2; j++) {
				arr[i][j] = arr[i][arr[0].length/2+j];
			}
		}
		// 3->2
		for (int i = 0; i < arr.length/2; i++) {
			for (int j = arr[0].length/2; j < arr[0].length; j++) {
				arr[i][j] = arr[arr.length/2+ i][j];
			}
		}
		// 4->3
		for (int i = arr.length/2; i < arr.length; i++) {
			for (int j = arr[0].length/2; j < arr[0].length; j++) {
				arr[i][j] = arr[i][j-arr[0].length/2];
			}
		}
		// 1->4
		for (int i = arr.length/2; i < arr.length; i++) {
			for (int j = 0; j < arr[0].length/2; j++) {
				arr[i][j] = temp[i-arr.length/2][j];
			}
		}
	}
}

//oper_1(상하 반전 함수)

//상단부 하단부 원소 스위칭

 

for (int n = 0; n < arr.length / 2; n++) {
for (int j = 0; j < arr[0].length; j++) {
temp = arr[n][j];
arr[n][j] = arr[arr.length - 1 - n][j];
arr[arr.length - 1 - n][j] = temp;
}
}

 

 

//oper_2(좌우 반전 함수)

//좌측 우측 원소 스위칭

//oper_2와 유사하므로 설명을 생략하겠습니다.

 

 

//oper_3(오른쪽으로 90도 회전)

//N*M 배열을 90도 회전한 값을 저장할 M*N 배열 arr_3을 새로 만들어 주고, 새로운 배열에 들어올 기존 값의 index를 계산해 회전한 값을 저장해줍니다.

//static 변수인 arr 배열을 M*N인 새로운 배열로 초기화 하고 arr_3의 내용을  arr에복사해줍니다.

 

int[][] arr_3 = new int[arr[0].length][arr.length];
for (int i = 0; i < arr[0].length; i++) {
for (int j = 0; j < arr.length; j++) {
arr_3[i][j] = arr[arr.length - 1 - j][i];
}
}
arr = new int[arr[0].length][arr.length];
for (int i = 0; i < arr_3.length; i++) {
for (int j = 0; j < arr_3[0].length; j++) {
arr[i][j] = arr_3[i][j];
}
}

 

 

//oper_4(왼쪽으로 90도 회전)

//oper_3과 유사하므로 설명을 생략하겠습니다.

 

 

//oper_5(부분 배열 시계방향 회전)

//1번 부분 배열을 temp 에 저장해준 뒤, 빈칸이 된 1번 부분배열 자리를 4번이, 

//빈칸이 된 4번 자리를 3번이, 빈칸이된 3번 자리를 2번이 차지하는 과정을 거쳐 

//마지막에 빈칸이된 2번 자리에 temp에 있던 1번 부분배열을 넣어주어 시계방향 회전을 구현했습니다.

 

int[][] temp = new int[arr.length/2][arr[0].length/2];
// 1번 부분 배열 temp에 저장
for (int i = 0; i < arr.length/2; i++) {
for (int j = 0; j < arr[0].length/2; j++) {
temp[i][j] = arr[i][j];
}
}
// 4->1
for (int i = 0; i < arr.length/2; i++) {
for (int j = 0; j < arr[0].length/2; j++) {
arr[i][j] = arr[arr.length/2 + i][j];
}
}
// 3->4
for (int i = arr.length/2; i < arr.length; i++) {
for (int j = 0; j < arr[0].length/2; j++) {
arr[i][j] = arr[i][arr[0].length/2+j];
}
}
// 2->3
for (int i = arr.length/2; i < arr.length; i++) {
for (int j = arr[0].length/2; j < arr[0].length; j++) {
arr[i][j] = arr[i-arr.length/2][j];
}
}
// 1->2
for (int i = 0; i < arr.length/2; i++) {
for (int j = arr[0].length/2; j < arr[0].length; j++) {
arr[i][j] = temp[i][j-arr[0].length/2];
}
}

 

 

//oper_6(부분 배열 반시계방향 회전)

//oper_5와  유사하므로 설명을 생략하겠습니다.

+ Recent posts