본문 바로가기
알고리즘 문제 풀이/프로그래머스

프로그래머스 등굣길 c++ (dp)

by 옹구스투스 2021. 6. 8.
반응형

문제 출처 : https://programmers.co.kr/learn/courses/30/lessons/42898

 

코딩테스트 연습 - 등굣길

계속되는 폭우로 일부 지역이 물에 잠겼습니다. 물에 잠기지 않은 지역을 통해 학교를 가려고 합니다. 집에서 학교까지 가는 길은 m x n 크기의 격자모양으로 나타낼 수 있습니다. 아래 그림은 m =

programmers.co.kr

문제 설명

계속되는 폭우로 일부 지역이 물에 잠겼습니다. 물에 잠기지 않은 지역을 통해 학교를 가려고 합니다. 집에서 학교까지 가는 길은 m x n 크기의 격자모양으로 나타낼 수 있습니다.

아래 그림은 m = 4, n = 3 인 경우입니다.

가장 왼쪽 위, 즉 집이 있는 곳의 좌표는 (1, 1)로 나타내고 가장 오른쪽 아래, 즉 학교가 있는 곳의 좌표는 (m, n)으로 나타냅니다.

격자의 크기 m, n과 물이 잠긴 지역의 좌표를 담은 2차원 배열 puddles이 매개변수로 주어집니다. 오른쪽과 아래쪽으로만 움직여 집에서 학교까지 갈 수 있는 최단경로의 개수를 1,000,000,007로 나눈 나머지를 return 하도록 solution 함수를 작성해주세요.

제한사항

  • 격자의 크기 m, n은 1 이상 100 이하인 자연수입니다.
    • m과 n이 모두 1인 경우는 입력으로 주어지지 않습니다.
  • 물에 잠긴 지역은 0개 이상 10개 이하입니다.
  • 집과 학교가 물에 잠긴 경우는 입력으로 주어지지 않습니다.

입출력 예

입출력 예 설명

풀이

'프로그래머스 / 동적계획법(Dynamic Programming) / 등굣길'로 분류되어 있는 문제이다.

처음엔 bfs로 풀었더니 효율성에서 시간 초과로 50점 맞았고,

dp로 푸니까 통과된 문제이다.

우선 해당 칸에 도착하는 길의 수를 저장할 2차원 배열 dp[101][101]을 생성하고,

물 웅덩이가 있는 부분은 -1을 넣는다.

조건에서 이동은 오른쪽, 아래쪽으로만 움직일 수 있으니, dp의 점화식은

dp[i][j] = dp[i-1][j] + dp[i][j-1]이고, 물 웅덩이가 있는 부분은 더하지 않는다.

 

 

코드1

#include <string>
#include <vector>
using namespace std;
    int dp[101][101];
int solution(int m, int n, vector<vector<int>> puddles) {
//m 가로 열
//n 세로 행
    dp[1][1]=1;

    for (int i = 0; i < puddles.size(); i++) { //물웅덩이는 -1
        dp[puddles[i][1]][puddles[i][0]] = -1;
    }
    for(int i=1; i<=n;i++){
        for(int j=1; j<=m; j++){
            int a=0;
            int b=0;
            if(dp[i][j]==-1)
                continue;
            if(dp[i-1][j]!=-1)
                a= dp[i-1][j];
            if(dp[i][j-1]!=-1)
                b= dp[i][j-1];
            dp[i][j]+=(a+b)%1000000007;
        }
    }

    return dp[n][m];
}

코드2(시간 초과)

#include <string>
#include <vector>
#include <queue>
#include <iostream>
#define DIV 1000000007
using namespace std;
int dir[2][2] = {{0,1},{1,0}};
int graph[101][101];
int count =0;

void bfs(int row, int col, int n, int m){

    queue<pair<int,int>> q;
    q.push({row,col});
    int a=0;
    while(!q.empty()){
        a++;
        int r =q.front().first;
        int c = q.front().second;
        q.pop();
        if(r==n&&c==m){
            count++;
            continue;
        }
        for(int i=0; i<2;i++){
            int next_r = r+dir[i][0];
            int next_c = c+dir[i][1];
            if(next_r<=n&&next_c<=m&&graph[next_r][next_c]!=-1){
                q.push({next_r,next_c});
            }
        }

    }


}

int solution(int m, int n, vector<vector<int>> puddles) {

    for(int i=0; i<puddles.size();i++){
        graph[puddles[i][1]][puddles[i][0]]=-1;
    }
    bfs(1,1,n,m);
    return count%DIV;
}
반응형

댓글