비트마스킹이 익숙하지 않다면, 아이디어가 떠오르지 않아 정말 어려울 문제입니다.
핵심 아이디어는 임의의 칸 (y, x)가 false
일 때 가로조각, true
일 때 세로조각이라고 가정하는 것입니다.
1 << (N * M)
연산으로 모든 가로조각과 세로조각 조합 경우의 수를 구할 수 있습니다.true
라면 해당 좌표는 세로조각, false
라면 가로조각인 것입니다.#include <iostream>
using namespace std;
int N, M, paper[4][4];
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
cin >> N >> M;
for (int y = 0; y < N; ++y){
string row;
cin >> row;
for (int x = 0; x < M; ++x)
paper[y][x] = row[x] - '0';
}
int answer = 0;
for (int i = 0; i < (1 << (N * M)); ++i) {
int sum = 0;
// [Case 1] 가로 조합을 계산합니다.
for (int y = 0; y < N; ++y) {
int value = 0;
for (int x = 0; x < M; ++x) {
if (i & (1 << (M * y + x))) {
sum += value;
value = 0;
} else {
value = 10 * value + paper[y][x];
}
}
sum += value;
}
// [Case 2] 세로 조합을 계산합니다.
for (int x = 0; x < M; ++x) {
int value = 0;
for (int y = 0; y < N; ++y) {
if (i & (1 << (M * y + x))) {
value = 10 * value + paper[y][x];
} else {
sum += value;
value = 0;
}
}
sum += value;
}
answer = max(answer, sum);
}
cout << answer << '\n';
}