Dino Rudy

[백준] 배열 돌리기 1_16926번 - 공룡 루디 본문

Algorithm/Baekjoon

[백준] 배열 돌리기 1_16926번 - 공룡 루디

Dino_Rudy 2021. 8. 14. 14:04

 배열 돌리기 1 16926번 solved.ac 실버 3 티어

https://www.acmicpc.net/problem/16926

 

16926번: 배열 돌리기 1

크기가 N×M인 배열이 있을 때, 배열을 돌려보려고 한다. 배열은 다음과 같이 반시계 방향으로 돌려야 한다. A[1][1] ← A[1][2] ← A[1][3] ← A[1][4] ← A[1][5] ↓ ↑ A[2][1] A[2][2] ← A[2][3] ← A[2][4] A[2][5]

www.acmicpc.net

 문제 해석

 

크기 N x M의 2차원 배열이 주어졌을 때 

모든 원소들을 반시계 방향으로 돌려야 합니다.

 

제가 풀이한 방법은

시계방향으로 돌리면서 앞에 있는 원소를 당겨 오는 방법입니다.

 

반시계 방향으로 돌리게 되면은 원소를 미는 방식으로 덮어쓰게 되는데

덮어쓰기 전에 기존 원소를 저장해야 하기 때문에

 

저는 시계방향으로 원소를 돌리면서

당겨오는 방식으로 문제를 풀었습니다.

 

전체 배열을 돌리는 방식은

테두리에 있는 원소를 돌리고

다시 안쪽의 배열중 테두리를 돌리는 방식으로

돌려 깎기? 식으로 배열을 돌렸습니다.

 

배열을 돌릴 때 기준 원소를 정하기 위해

왼쪽 가장 위 원소를 기준으로 정했고

왼쪽 가장 위 원소를 기준으로 했을 시

시계방향은 오른쪽-> 아래-> 왼쪽-> 위 방향의 반복입니다.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class Main {

	public static int n, m, r, min;
	public static int[][] arr;
	public static int[][] tmp;

	public static int[] dr = { 0, 1, 0, -1 }; // 오른쪽 ->아래->왼쪽->위 방향 순서
	public static int[] dc = { 1, 0, -1, 0 }; // 오른쪽 ->아래->왼쪽->위 방향 순서

	public static void rotate(int s, int bottom_r, int right_c, int rotator) {
		if (s > min)
			return;
		else {
			int ro=rotator%((bottom_r-s+right_c-s)*2); // 방향을 일정하게 하고 돌리게 되면 제자리로 돌아오는
													//경우를 구해 많이 돌리게 될시 연산을 줄이는 효과를 볼 수 있습니다.
			for (int i = 0; i < ro; i++) {
				int tmp = arr[s][s]; //기준이 되는 원소를 임시 저장해줘야 합니다.
				int dir = 0;
				int before_r = s;
				int before_c = s;
				int next_r = -1;
				int next_c = -1;

				while (dir <= 3) { //오른쪽 -> 아래 ->왼쪽 ->위 순서로 돌고나면 끝이나게 됩니다.
					if (before_r + dr[dir] >= s && before_r + dr[dir] <= bottom_r && before_c + dc[dir] >= s
							&& before_c + dc[dir] <= right_c) {
						next_r = before_r + dr[dir];
						next_c = before_c + dc[dir];
						arr[before_r][before_c] = arr[next_r][next_c];
						before_r = next_r;
						before_c = next_c;
					} else {
						dir++;
					}

				}

				arr[s + 1][s] = tmp; //기준이되는 원소 아래에 있는 원소는 다른원소(기준원소의 오른쪽)를 땡기게되므로
									//저장해 둔 임시원소를 덮어씁니다.
			}
			rotate(s + 1, bottom_r - 1, right_c - 1, rotator);//기준원소와 테두리 경계가 바뀌면서 함수 호출
		}

	}

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

		String[] inp = br.readLine().split(" ");
		n = Integer.parseInt(inp[0]);
		m = Integer.parseInt(inp[1]);
		r = Integer.parseInt(inp[2]);

		arr = new int[n][m];
		tmp = new int[n][m];
		min = (n < m ? n : m)/2-1; //배열 돌리기에서 끝나는 조건입니다.
		for (int i = 0; i < n; i++) {
			inp = br.readLine().split(" ");
			for (int j = 0; j < inp.length; j++)
				arr[i][j] = Integer.parseInt(inp[j]);
		}

		rotate(0, n - 1, m - 1, r);

		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++)
				bw.write(arr[i][j] + " ");
			bw.write("\n");
		}
		bw.close();
	}
}