[BOJ17406] 배열돌리기4

2 분 소요

[BOJ17406] 배열돌리기4

문제 링크

문제 설명

  • 배열을 입력받고, 범위 명령어를 통해 그 범위만큼의 배열을 오른쪽으로 회전시킨다.
  • 범위 명령어는 최대 6번까지 입력받을 수 있다.
  • 배열을 명령 횟수만큼 회전시킨후, 행별로 배열의 합중 최소를 출력하는 문제이다.
  • 명령의 순서는 임의로 정할 수 있다.

코드 리뷰

  • 회전시키는 부분은 예전 삼성전자 코딩테스트에서 미세먼지 안녕이라는 문제에서 했던 부분과 비슷했다.
  • 범위 명령어는 (r,c,s) 로 입력을 받는데, (r-s,c-s) 에서 (r+s,c+s) 만큼의 정사각형 배열을 오른쪽으로 회전시키면 된다.
  • 재귀를 통해 s를 1씩 감소시키며 바깥쪽 테두리부터 회전을 시킨다. s가 0이되면 더이상 회전시킬 배열이 없으므로 리턴시킨다.
  • 명령의 순서는 nextpermutation을 통해 순열로 모든 경우의 수만큼 실행을 하였다.
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;

typedef struct {
	int r;
	int c;
	int s;
}spinning;

vector <spinning> v;
int arr[7] = { 0,1,2,3,4,5,6 };
int N, M, K;
int board[53][53];
int copyboard[53][53];

void spin(int r, int c, int s) {
	if (s == 0) return;
	else {
		int tmp = 0;
		int tmp2 = 0;
		for (int i = c + s; i >= c-s; i--) {
			if (i == c + s) tmp = copyboard[r-s][i];
			else copyboard[r-s][i + 1] = copyboard[r-s][i];
		}
		for (int i = r + s; i > r - s; i--) {
			if (i == r + s) {
				tmp2 = copyboard[i][c + s];
				copyboard[i][c + s] = copyboard[i - 1][c + s];
			}
			else if (i == r - s + 1) {
				copyboard[i][c + s] = tmp;
				tmp = 0;
			}
			else copyboard[i][c + s] = copyboard[i-1][c + s];
		}
		for (int i = c - s; i < c + s; i++) {
			if (i == c - s) {
				tmp = copyboard[r + s][i];
				copyboard[r + s][i] = copyboard[r + s][i + 1];
			}
			else if (i == c + s - 1) {
				copyboard[r + s][i] = tmp2;
				tmp2 = 0;
			}
			else copyboard[r + s][i] = copyboard[r + s][i + 1];
		}
		for (int i = r - s; i < r + s; i++) {
			if (i == r + s - 1) copyboard[i][c - s] = tmp;
			else copyboard[i][c - s] = copyboard[i + 1][c - s];
		}
		spin(r, c, s - 1);
	}
}
int main() {
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> N >> M >> K;
	int Min = 0;
	int ans = 100000000;
	for (int n = 1; n <= N; n++) {
		for (int m = 1; m <= M; m++) {
			cin >> board[n][m];
		}
	}
	int range = K;
	while (range--) {
		int r, c, s;
		cin >> r >> c >> s;
		v.push_back({ r,c,s });
	}
	do {
		for (int n = 1; n <= N; n++) {
			for (int m = 1; m <= M; m++) {
				copyboard[n][m] = board[n][m];
			}
		}
		for (int i = 0; i < K; i++) {
			spin(v[arr[i]].r,v[arr[i]].c,v[arr[i]].s);
		}
		for (int n = 1; n <= N; n++) {
			for (int m = 1; m <= M; m++) {
				Min += copyboard[n][m];
			}
			ans = min(ans, Min);
			Min = 0;
		}
	} while (next_permutation(arr,arr + K));
	cout << ans << '\n';
	return 0;
}

댓글남기기