문제 풀이/백준 알고리즘

[baekjoon 16926] 배열 돌리기 1 (구현) (C++)

dev_beomgeun 2022. 2. 10. 02:08
728x90

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

구현 문제를 잘 못 푸는 나에게 어려웠던 문제이다. 기본적인 배열 돌리기도 힘들어하다니.. 연습이 시급하다.

 

생각해볼 포인트는 두 가지이다.

 

1. 구현의 영역인 배열의 값을 한 칸씩 반시계 방향으로 옮기기

2. 사각형 모양의 배열들이 독립적으로 회전해야 하는 것

이런 식으로, 외곽 배열과 내부 배열은 독립적으로 회전한다.

 

잘 생각해서, 인덱스 접근만 잘한다면 나머지는 배열의 값을 이동하면 된다.

 

1. 반시계 방향으로 배열의 값을 돌리기

- 이 부분은, 동서남북 방향 모두 각각 옮겨줘야 한다.

- 위의 사진을 참고하면, [1][1] ~ [1][5], [1][5] ~ [4][5], [4][5] ~ [4][1], [4][1] ~ [1][1]으로 인덱스를 계산해주면 된다.

- 제일 외곽은 0~x-1, 0~y-1이지만 내부 사각형은 1칸씩 줄어드는 것을 생각해야 한다.

(최소, 최대 모두 1씩 감소시켜줘야 한다)

 

2. 독립적으로 회전, 얼마나 회전?

- 문제의 조건을 생각해보면, 

  • min(N, M) mod 2 = 0

가 등장한다. 즉, 가로 또는 세로의 최솟값은 짝수이고, 해당 값을 2로 나눈 값이 사각형의 개수를 결정한다.

 

#include <iostream>
#include <cmath>

using namespace std;

int n, m, r;
int arr[301][301];

void rotation(int x, int y) {

	int count = min(x, y) / 2;

	for (int c = 0; c < count; c++) {
		int xMax = x - c - 1;
		int yMax = y - c - 1;

		int start = arr[c][c];

		for (int j = c; j < yMax; j++) { // 왼 <- 오
			arr[c][j] = arr[c][j + 1]; 
		}
		for (int i = c; i < xMax; i++) { // 위 <- 아래 
			arr[i][yMax] = arr[i+1][yMax]; 
		}
		for (int j = yMax; j > c; j--) { // 오 <- 왼
			arr[xMax][j] = arr[xMax][j-1];
		}
		for (int i = xMax; i > c; i--) { // 아래 <- 위
			arr[i][c] = arr[i-1][c];
		}
		arr[c + 1][c] = start; // 시작값으로 바꿔주기
	}
}

int main() {
	cin >> n >> m >> r;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> arr[i][j];
		}
	}

	for (int i = 0; i < r; i++) {
		rotation(n, m);
	}

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

 

728x90