ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준] 14925번 목장 건설하기
    문제 풀이 2020. 7. 11. 17:51

    14925번 목장 건설하기


    문제


    랜드 씨는 퇴직금으로 땅을 사서 목장을 지으려 한다.  그가 사려고 소개받은 땅은 직사각형이고 대부분 들판이지만, 여기저기에 베기 어려운 나무와 치울 수 없는 바위가 있다.

    그는 목장을 하나의 정사각형으로 최대한 크게 지으려 하는데, 그 안에 나무나 바위는 없어야 한다. 

    땅의 세로 길이가 M미터, 가로 길이가 N미터일 때, 1미터 간격의 격자로 된 땅의 지도를 M x N행렬로 표현하자. 

    이때, 행렬의 원소 0은 들판, 1은 나무 그리고 2는 돌을 의미한다.  랜드씨의 땅에서 지을 수 있는 가장 큰 정사각형 목장의 한 변의 크기 L을 출력하시오.


    입력


    M N

    M x N 행렬

    1 <= M <= 100

    1 <= N <= 1000


    출력


    L



    풀이)

    처음에 for문을 이용해서 풀었다가 시간초과가 난 문제이다.

    예외처리를 많이 해주면 괜찮을 줄 알았는데 아니였다.

    dp를 이용해서 풀어야하는 문제이다


    점화식

    dp[i][j] = i행 j열 칸까지 봤을 때 나올 수 있는 정사각형 길이 최대값


    각 칸을 살펴볼 때, 이 칸이 정사각형을 이루는 오른쪽 아래칸이라고 생각한다.


     

     

     

     


     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     


     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     


    따라서 나무나 돌이 있는 칸은 넘기고, 들판이 있는 칸을 계산할 때 위쪽, 왼쪽, 왼쪽 위 대각선

    나올 수 있는 정사각형 길이의 최소값을 찾은 뒤 그 길이에 +1을 해주면 된다.

    (그 길이보다 1 정도 긴 정사각형이 만들어질 수 있다는 뜻)


    dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1


    나올 수 있는 가장 큰 정사각형 길이는 dp[][]배열 중 가장 큰 값


    코드)


    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
    #include <stdio.h>
    #include <algorithm>
    using namespace std;
     
    int M, N;
    int map[1001][1001];
    int dp[1001][1001];
     
    int main() {
        scanf("%d %d"&M, &N);
        for (int i = 1; i <= M; i++) {
            for (int j = 1; j <= N; j++) {
                scanf("%d"&map[i][j]);
            }
        }
        int len = 0;
        for (int i = 1; i <= M; i++) {
            for (int j = 1; j <= N; j++) {
                if (map[i][j] > 0continue;
                //위, 왼쪽, 왼쪽위 대각선
                dp[i][j] = min(min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1;
                len = max(len, dp[i][j]);
            }
        }
        printf("%d", len);
        return 0;
    }
    cs


    '문제 풀이' 카테고리의 다른 글

    [백준] 13537번 수열과 쿼리1  (0) 2020.07.13
    [백준] 11048번 이동하기  (0) 2020.07.11
    [백준] 10942번 팰린드롬  (0) 2020.07.10
    [백준] 9370번 미확인 도착지  (0) 2020.07.09
    [백준] 1541번 잃어버린 괄호  (0) 2020.07.08

    댓글

Designed by Tistory.