본문 바로가기

Algorithm

[백준 16935] 배열 돌리기3(Java)

반응형

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

예제 입력 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

풀이 설명

1. 입력받은 연산 종류에 따라 switch문으로 나누고, 각각에 해당하는 함수를 선언, 호출한다.

2. 모든 연산에서 인덱스만 잘 조절, 조합하면 해결된다.

Java 코드

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

public class Main {
	private static int[][] arr;
	private static int h;
	private static int w;
	private static int r;

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		h = Integer.parseInt(st.nextToken());
		w = Integer.parseInt(st.nextToken());
		r = Integer.parseInt(st.nextToken());
		
		arr = new int[h][w];
		for(int i=0; i<h; i++) {
			st = new StringTokenizer(br.readLine());
			for(int j=0; j<w; j++) {
				arr[i][j] = Integer.parseInt(st.nextToken());
			}
		}
		
		String[] num = br.readLine().split(" ");
		for(int menu=0; menu<num.length; menu++) {
			switch(num[menu]) {
			case "1": //상하반전
				upDown();
				break;
			case "2": //좌우반전
				leftRight();
				break;
			case "3": //오른쪽 90도
				arr = right();
				break;
			case "4": //왼쪽 90도
				arr = left();
				break;
			case "5": //4그룹 분할 후 시계방향 한 번 회전
				quadClockWise();
				break;
			case "6": //4그룹 분할 후 반시계방향 회전
				quadAntiClockWise();
				break;
			}
		}
		
		StringBuilder sb = new StringBuilder();
		for(int i=0; i<h; i++) {
			for(int j=0; j<w; j++) {
				sb.append(arr[i][j]).append(" ");
			}
			sb.append("\n");
		}
		System.out.println(sb);
	}

	private static void upDown() {
		int halfh = h/2;
		for(int i=0; i<halfh; i++) {
			for(int j=0; j<w; j++) {
				int temp = arr[i][j];
				arr[i][j] = arr[h-1-i][j];
				arr[h-1-i][j] = temp;
			}
		}
	}

	private static void leftRight() {
		int halfw = w/2;
		for(int i=0; i<h; i++) {
			for(int j=0; j<halfw; j++) {
				int temp = arr[i][j];
				arr[i][j] = arr[i][w-1-j];
				arr[i][w-1-j] = temp;
			}
		}
	}
	
	private static int[][] right() {
		int[][] newArr = new int[w][h];
		
		for(int i=0; i<w; i++) {
			int[] add = new int[h];
			for(int j=0; j<h; j++) {
				add[j] = arr[h-1-j][i];
			}
			newArr[i] = add;
		}
		int temp = w;
		w = h;
		h = temp;
		return newArr;
	}
	
	private static int[][] left() {
		int[][] newArr = new int[w][h];
		
		for(int i=0; i<w; i++) {
			int[] add = new int[h];
			for(int j=0; j<h; j++) {
				add[j] = arr[j][w-1-i];
			}
			newArr[i] = add;
		}
		int temp = w;
		w = h;
		h = temp;
		return newArr;
	}
	
	private static void quadClockWise() {
		int halfw = w/2;
		int halfh = h/2;
		int[][] a = new int[halfh][halfw];
		int[][] b = new int[halfh][halfw];
		int[][] c = new int[halfh][halfw];
		int[][] d = new int[halfh][halfw];
		////a,b,c,d 구역으로 나눈다 - 북서, 북동, 남서, 남동 순서
		for(int i=0; i<h; i++) {
			for(int j=0; j<w; j++) {
				if(i<halfh && j<halfw)
					a[i][j] = arr[i][j];
				else if(i<halfh && j>=halfw)
					b[i][j-halfw] = arr[i][j];
				else if(i>=halfh && j<halfw)
					c[i-halfh][j] = arr[i][j];
				else
					d[i-halfh][j-halfw] = arr[i][j];
			}
		}
		////시계방향으로 재조립한다.
		for(int i=0; i<h; i++) {
			for(int j=0; j<w; j++) {
				if(i<halfh && j<halfw)
					arr[i][j] = c[i][j];
				else if(i<halfh && j>=halfw)
					arr[i][j] = a[i][j-halfw];
				else if(i>=halfh && j<halfw)
					arr[i][j] = d[i-halfh][j];
				else
					arr[i][j] = b[i-halfh][j-halfw];
			}
		}
	}
	
	private static void quadAntiClockWise() {
		int halfw = w/2;
		int halfh = h/2;
		int[][] a = new int[halfh][halfw];
		int[][] b = new int[halfh][halfw];
		int[][] c = new int[halfh][halfw];
		int[][] d = new int[halfh][halfw];
		////a,b,c,d 구역으로 나눈다 - 북서, 북동, 남서, 남동 순서
		for(int i=0; i<h; i++) {
			for(int j=0; j<w; j++) {
				if(i<halfh && j<halfw)
					a[i][j] = arr[i][j];
				else if(i<halfh && j>=halfw)
					b[i][j-halfw] = arr[i][j];
				else if(i>=halfh && j<halfw)
					c[i-halfh][j] = arr[i][j];
				else
					d[i-halfh][j-halfw] = arr[i][j];
			}
		}
		////반시계방향으로 재조립한다.
		for(int i=0; i<h; i++) {
			for(int j=0; j<w; j++) {
				if(i<halfh && j<halfw)
					arr[i][j] = b[i][j];
				else if(i<halfh && j>=halfw)
					arr[i][j] = d[i][j-halfw];
				else if(i>=halfh && j<halfw)
					arr[i][j] = a[i-halfh][j];
				else
					arr[i][j] = c[i-halfh][j-halfw];
			}
		}
	}
}
반응형

'Algorithm' 카테고리의 다른 글

[백준 18258] 큐 2(Python, Java)  (0) 2021.02.11
[백준 17406] 배열 돌리기4(Java)  (0) 2021.02.10
[백준 16926] 배열 돌리기1(Java)  (0) 2021.02.10
[백준 1068] 트리(Python)  (2) 2021.02.10
[백준 1158] 요세푸스 문제(Java)  (0) 2021.02.09