Algorithm/삼성 SW Expert
2112. [모의 SW 역량테스트] 보호 필름
48965
2024. 3. 20. 20:58
풀이
- 먼저 배열 탐색을 통해 합격 기준을 판별하는 함수인 checkPass() 함수를 구현한다.
- 해당 함수는 각 행들을 탐색하며 연속으로 K개의 숫자가 있는지 판별하며, 특정 행에서 이를 만족시키지 못하면 false를 반환하고 모두 통과하게 되면 true를 반환한다.
- 이후 각 테스트케이스마다 checkPass()함수를 실행 후, 한번에 통과하지 못하면 백트래킹 함수를 실행한다.
- 백트래킹 함수의 파라미터는 행의 레벨, 바뀐 행의 수로 세팅하였다. 또한 백트래킹 함수의 가지치기 조건으로는 변환 횟수가 현재 최소 변환 수보다 크게 되면 반환하도록 하였다.
- 바텀-업 방식을 사용하여, 먼저 가장 마지막 행까지 재귀를 돌린 후, 돌아오는 과정에서 각 행들을 A(0), B(로) 각각 채우며, 바뀐 횟수를 증가시켜 마지막 행에 이르면 checkPass() 함수를 통해 최소 변경 횟수를 구한다.
- 함수 내에서 각 행들을 바꾸고 돌아오는 과정에서 기존 값들을 임시 저장시킨 값으로 다시 복구해주었다.
#include <iostream>
#include <algorithm>
using namespace std;
int T, D, W, K;
int arr[14][21];
int ans;
bool checkPass() {
for (int j = 0; j < W; j++) {
int maxCnt = 1;
int cnt = 1;
for (int i = 1; i < D; i++) {
if (arr[i][j] == arr[i - 1][j]) {
cnt++;
maxCnt = max(maxCnt, cnt);
} else {
cnt = 1;
}
}
if (maxCnt < K) return false;
}
return true;
}
void BT(int lev, int changed) {
if (changed >= ans) return;
if (lev == D) {
if (checkPass())
ans = min(ans, changed);
return;
}
BT(lev + 1, changed);
int tmp[21];
for (int j = 0; j < W; j++)
tmp[j] = arr[lev][j];
for (int j = 0; j < W; j++)
arr[lev][j] = 0;
BT(lev + 1, changed + 1);
for (int j = 0; j < W; j++)
arr[lev][j] = 1;
BT(lev + 1, changed + 1);
for (int j = 0; j < W; j++)
arr[lev][j] = tmp[j];
}
int main() {
cin >> T;
for (int k = 0; k < T; k++) {
ans = 30;
cin >> D >> W >> K;
for (int i = 0; i < D; i++)
for (int j = 0; j < W; j++)
cin >> arr[i][j];
if (checkPass()) {
cout << "#" << k + 1 << " " << 0 << "\n";
continue;
}
BT(0, 0);
cout << "#" << k + 1 << " " << ans << "\n";
}
return 0;
}