ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 14500 (테트로미노) c++
    백준 문제 2022. 8. 21. 00:25
    728x90

    문제

     

    14500번: 테트로미노

    폴리오미노란 크기가 1×1인 정사각형을 여러 개 이어서 붙인 도형이며, 다음과 같은 조건을 만족해야 한다. 정사각형은 서로 겹치면 안 된다. 도형은 모두 연결되어 있어야 한다. 정사각형의 변

    www.acmicpc.net

    n * m 의 공간은 한 칸당 1이상 1000이하의 수를 가집니다. 

    이 때 다음과 같은 공간의 합의 최대를 구하는 문제입니다.

    위의 공간은 n * m의 공간에서 상하좌우로 대칭이 가능합니다.

     

    처음에 이 문제를 접근할 때에는 n * m 배열에서 첫번째 인덱스 부터 시작해서

    위의 도형을 차례대로 대칭하면서 최댓값을 구하려 했지만 시간이 너무 많이 들고 구현에 어려움이 있었습니다.

     

    하지만 자세히 도형들을 살펴보면 ㅜ 모형을 제외한 나머지 도형들은 dfs 탐색으로 깊이가 3으로 통일 됩니다.

    따라서 첫번째 기준점을 잡고 깊이가 3인 dfs를 진행하면 ㅜ를 제외한 나머지 도형들에 대해서

    최댓값을 알 수 있습니다.

    depth가 3이되면 ans를 갱신해 줍니다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    void dfs(int x, int y, int sum, int depth) {
        visit[x][y] = true;
        if (depth == 3) {
            ans = max(ans, sum);
            return;
        }
        for (int i = 0; i < 4; i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if (nx < 0 || ny < 0 || nx >= n || ny >= m) continue;
            if (visit[nx][ny])continue;
            dfs(nx, ny, sum + arr[nx][ny], depth + 1);
            visit[nx][ny] = false;
        }
    }
    cs

     

    이제 ㅜ 모형을 생각해 줘야 합니다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            memset(visit, falsesizeof(visit));
            dfs(i, j, arr[i][j], 0);
            if (i - 1 >= 0 && j + 2 < m) { // ㅗ
                int temp = 0;
                temp = arr[i][j] + arr[i][j + 1+ arr[i][j + 2+ arr[i - 1][j + 1];
                ans = max(temp, ans);
            }
            if (j + 2 < m && i + 1 < n) { //ㅜ
                int temp = 0;
                temp = arr[i][j] + arr[i][j + 1+ arr[i][j + 2+ arr[i + 1][j + 1];
                ans = max(temp, ans);
            }
            if (i + 2 < n && j + 1 < m) { //ㅏ
                int temp = 0;
                temp = arr[i][j] + arr[i + 1][j] + arr[i + 2][j] + arr[i + 1][j + 1];
                ans = max(temp, ans);
            }
            if (i + 1 < n && i - 1 >= 0 && j + 1 < m) { //ㅓ
                int temp = 0;
                temp = arr[i][j] + arr[i - 1][j + 1+ arr[i][j + 1+ arr[i + 1][j + 1];
                ans = max(temp, ans);
            }
        }
    }
    cs

    전체 코드입니다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <string>
    #include <stack>
    #include <queue>
    #include <deque>
    #include <cmath>
    #include <map>
    #include <set>
    #include <tuple>
    #define MAX 2100000000
    #define inf LONG_MAX
    #define big(a, b) a > b ? a : b
    using namespace std;
    using ll = long long;
    using ull = unsigned long long;
    int n, m;
    int arr[501][501];
    bool visit[501][501];
    int ans;
    int dx[4= { 010-1 };
    int dy[4= { 1,0-10 };
    void dfs(int x, int y, int sum, int cnt);
    int main() {
        ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
        cin >> n >> m;
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                cin >> arr[i][j];
     
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                memset(visit, falsesizeof(visit));
                dfs(i, j, arr[i][j], 0);
                if (i - 1 >= 0 && j + 2 < m) { // ㅗ
                    int temp = 0;
                    temp = arr[i][j] + arr[i][j + 1+ arr[i][j + 2+ arr[i - 1][j + 1];
                    ans = max(temp, ans);
                }
                if (j + 2 < m && i + 1 < n) { //ㅜ
                    int temp = 0;
                    temp = arr[i][j] + arr[i][j + 1+ arr[i][j + 2+ arr[i + 1][j + 1];
                    ans = max(temp, ans);
                }
                if (i + 2 < n && j + 1 < m) { //ㅏ
                    int temp = 0;
                    temp = arr[i][j] + arr[i + 1][j] + arr[i + 2][j] + arr[i + 1][j + 1];
                    ans = max(temp, ans);
                }
                if (i + 1 < n && i - 1 >= 0 && j + 1 < m) { //ㅓ
                    int temp = 0;
                    temp = arr[i][j] + arr[i - 1][j + 1+ arr[i][j + 1+ arr[i + 1][j + 1];
                    ans = max(temp, ans);
                }
            }
        }
     
        cout << ans;
        return 0;
    }
    void dfs(int x, int y, int sum, int depth) {
        visit[x][y] = true;
        if (depth == 3) {
            ans = max(ans, sum);
            return;
        }
        for (int i = 0; i < 4; i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if (nx < 0 || ny < 0 || nx >= n || ny >= m) continue;
            if (visit[nx][ny])continue;
            dfs(nx, ny, sum + arr[nx][ny], depth + 1);
            visit[nx][ny] = false;
        }
    }
        
     
     
    cs

    '백준 문제' 카테고리의 다른 글

    백준 1629 (곱셈) c++  (0) 2022.08.26
    백준 2407 (조합) c++  (0) 2022.08.22
    백준 9019 (DSLR) C++  (0) 2022.08.18
    백준 7662 (이중 우선순위 큐) c++  (0) 2022.08.16
    백준 5430 (AC) C++  (0) 2022.08.10
Designed by Tistory.