문제 링크: https://www.acmicpc.net/problem/17406
브루트포스 문제입니다.
배열이 주어지고, 회전 연산 k개가 주어집니다. 배열의 값 = 배열 한 행의 합 중에서 최소값인데 회전 연산의 순서를 요리조리 바꿨을 때 배열의 값 중 최소값을 구하는 문제입니다.
순열 만드는건 어렵지 않습니다. 회전 연산을 정렬시킨 다음 std::next_permutation을 사용하면 됩니다.
문제는 회전인데.. 생각해보니까 위 사진처럼 한 원소를 잡고 반시계방향으로 계속 swap하면서 원래 위치 직전까지 한개씩 swap 하면 시계방향으로 한칸씩 회전시킨 것과 같아집니다.
이런식으로 풀면 됩니다
#include <bits/stdc++.h>
using namespace std;
int arr_org[50][50];
const int dy[] = {-1, 0, 1, 0};
const int dx[] = {0, -1, 0, 1};
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int n, m, k;
cin >> n >> m >> k;
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
cin >> arr_org[i][j];
int mn = 1e9;
vector<tuple<int, int, int>> ops(k);
for (auto& [r, c, s] : ops) {
cin >> r >> c >> s;
--r, --c;
}
sort(ops.begin(), ops.end());
do {
int arr[50][50];
memcpy(arr, arr_org, sizeof(arr_org));
for (const auto& [r, c, s] : ops) {
for (int i = s; i > 0; --i) {
int curr_y = r + i;
int curr_x = c + i;
for (int j = 0; j < 4; ++j) { //dir
for (int k = 0; k < 2 * i; ++k) {
if (j == 3 && k == 2 * i - 1) break;
int next_y = curr_y + dy[j];
int next_x = curr_x + dx[j];
swap(arr[curr_y][curr_x], arr[next_y][next_x]);
curr_y = next_y;
curr_x = next_x;
}
}
}
}
for (int i = 0; i < n; ++i)
mn = min(mn, accumulate(arr[i], arr[i]+m, 0));
} while (next_permutation(ops.begin(), ops.end()));
cout << mn << '\n';
return 0;
}
반응형
'Online Judge > 백준' 카테고리의 다른 글
[백준][C++] 1202: 보석 도둑 (0) | 2020.07.30 |
---|---|
[백준][C++] 15658: 연산자 끼워넣기 (2) (0) | 2020.07.29 |
[백준][C++] 18891: 제21대 국회의원 선거 (0) | 2020.07.29 |
[백준][C++] 1007: 벡터 매칭 (0) | 2020.07.28 |
[백준][C++] 1173: 운동 (0) | 2020.07.27 |