[BOJ] 14500번 테트로미노 c++

chowisely·2020년 10월 9일
0

BOJ

목록 보기
30/70

https://www.acmicpc.net/problem/14500

문제
폴리오미노란 크기가 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 + 예외 경우 처리로 풀었다.

0개의 댓글