문제
폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다.
- 정사각형은 서로 겹치면 안 된다.
- 도형은 모두 연결되어 있어야 한다.
- 정사각형의 변끼리 연결되어 있어야 한다. 즉, 꼭짓점과 꼭짓점만 맞닿아 있으면 안 된다.
정사각형 4개를 이어 붙인 폴리오미노는 테트로미노라고 하며, 다음과 같은 5가지가 있다.
아름이는 크기가 N×M인 종이 위에 테트로미노 하나를 놓으려고 한다. 종이는 1×1 크기의 칸으로 나누어져 있으며, 각각의 칸에는 정수가 하나 쓰여 있다. 테트로미노 하나를 적절히 놓아서 테트로미노가 놓인 칸에 쓰여 있는 수들의 합을 최대로 하는 프로그램을 작성하시오. 테트로미노는 반드시 한 정사각형이 정확히 하나의 칸을 포함하도록 놓아야 하며, 회전이나 대칭을 시켜도 된다.
입력 1
5 5
1 2 3 4 5
5 4 3 2 1
2 3 4 5 6
6 5 4 3 2
1 2 1 2 1
출력 1
19
입력 2
4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
출력 2
20
입력 3
4 10
1 2 1 2 1 2 1 2 1 2
2 1 2 1 2 1 2 1 2 1
1 2 1 2 1 2 1 2 1 2
2 1 2 1 2 1 2 1 2 1
출력 3
7
#include <iostream>
#include <cstdio>
#include <queue>
#include <utility>
#include <cstring>
using namespace std;
int N, M;
int arr[500][500];
bool visit[500][500] = {false,};
int maxval = 0;
int nx, ny;
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
void find_max1(int x, int y, int cnt, int sum) {
if(cnt == 4) {
maxval = max(maxval, sum);
return;
}
for (int k = 0; k < 4; k++) {
int nx = x + dx[k];
int ny = y + dy[k];
if (nx < 0 || ny < 0 || nx >= N || ny >= M) continue;
if (visit[nx][ny] == false) {
visit[nx][ny] = true;
find_max1(nx, ny, cnt + 1, sum + arr[nx][ny]);
visit[nx][ny] = false;
}
}
}
void find_max2(int x, int y) {
// ㅗ
if(x - 1 > -1 && y + 2 < M)
maxval = max(maxval, arr[x][y] + arr[x][y + 1] + arr[x][y + 2] + arr[x - 1][y + 1]);
// ㅜ
if(x + 1 < N && y + 2 < M)
maxval = max(maxval, arr[x][y] + arr[x][y + 1] + arr[x][y + 2] + arr[x + 1][y + 1]);
// ㅓ
if(x - 1 > -1 && x + 1 < N && y + 1 < M)
maxval = max(maxval, arr[x][y] + arr[x - 1][y + 1] + arr[x][y + 1] + arr[x + 1][y + 1]);
// ㅏ
if(x - 1 > -1 && x + 1 < N && y + 1 < M)
maxval = max(maxval, arr[x][y] + arr[x - 1][y] + arr[x + 1][y] + arr[x][y + 1]);
}
int main() {
scanf("%d %d", &N, &M);
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
scanf("%d", &arr[i][j]);
}
}
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
visit[i][j] = true;
find_max1(i, j, 1, arr[i][j]);
visit[i][j] = false;
find_max2(i, j);
}
}
printf("%d\n", maxval);
}
처음에 DFS로 풀까 싶었는데 ㅗ, ㅜ, ㅓ, ㅏ는 DFS로 나올 수 없는 케이스라
위 사진 처럼 베이스 블럭을 두고 확장시키려 했다. 테스트케이스는 통과했는데 시간초과가 떠서 결국 DFS + 예외 경우 처리로 풀었다.