-
[프로그래머스] 보행자 천국문제 풀이 2020. 6. 1. 00:25
문제 설명
보행자 천국
카카오내비 개발자인 제이지는 시내 중심가의 경로 탐색 알고리즘 개발 업무를 담당하고 있다. 최근 들어 보행자가 자유롭고 편리하게 걸을 수 있도록 보행자 중심의 교통 체계가 도입되면서 도심의 일부 구역은 자동차 통행이 금지되고, 일부 교차로에서는 보행자 안전을 위해 좌회전이나 우회전이 금지되기도 했다. 복잡해진 도로 환경으로 인해 기존의 경로 탐색 알고리즘을 보완해야 할 필요가 생겼다.
도시 중심가의 지도는
m × n
크기의 격자 모양 배열city_map
으로 주어진다. 자동차는 오른쪽 또는 아래 방향으로 한 칸씩 이동 가능하다.city_map[i][j]
에는 도로의 상황을 나타내는 값이 저장되어 있다.0
인 경우에는 자동차가 자유롭게 지나갈 수 있다.1
인 경우에는 자동차 통행이 금지되어 지나갈 수 없다.2
인 경우는 보행자 안전을 위해 좌회전이나 우회전이 금지된다. (왼쪽에서 오던 차는 오른쪽으로만, 위에서 오던 차는 아래쪽으로만 진행 가능하다)
도시의 도로 상태가 입력으로 주어졌을 때, 왼쪽 위의 출발점에서 오른쪽 아래 도착점까지 자동차로 이동 가능한 전체 가능한 경로 수를 출력하는 프로그램을 작성하라. 이때 가능한 경로의 수는 컴퓨터가 표현할 수 있는 정수의 범위를 넘어설 수 있으므로, 가능한 경로 수를
20170805
로 나눈 나머지 값을 출력하라.입력 형식
입력은 도시의 크기를 나타내는
m
과n
, 그리고 지도를 나타내는 2차원 배열city_map
으로 주어진다. 제한조건은 아래와 같다.1 <= m, n <= 500
city_map
의 크기는m × n
이다.- 배열의 모든 원소의 값은
0
,1
,2
중 하나이다. - 출발점의 좌표는
(0, 0)
, 도착점의 좌표는(m - 1, n - 1)
이다. - 출발점과 도착점의
city_map[i][j]
값은0
이다.
출력 형식
출발점에서 도착점까지 이동 가능한 전체 경로의 수를
20170805
로 나눈 나머지를 리턴한다.예제 입출력
m n city_map answer 3 3 [[0, 0, 0], [0, 0, 0], [0, 0, 0]] 6 3 6 [[0, 2, 0, 0, 0, 2], [0, 0, 2, 0, 1, 0], [1, 0, 0, 2, 2, 0]] 2 풀이)
dfs, bfs를 이용하면 시간초과가 나는 문제이다.
dp를 이용해서 풀어야 한다.
city_map이 2일 경우를 어떻게 처리할지 몰라, 결국 다른 분의 포스팅을 보고 풀게 되었다.
2가지 방향의 배열로 나눠서 푸는 방법이었다.
참고 블로그 주소) https://greenapple16.tistory.com/33
코드)
#include <vector> using namespace std; int MOD = 20170805; // 전역 변수를 정의할 경우 함수 내에 초기화 코드를 꼭 작성해주세요. int solution(int m, int n, vector<vector<int>> city_map) { int answer = 0; vector<vector<int>> right(m+1,vector<int>(n+1,0)); //y행 x열에서 오른쪽으로 갈수있는 경우 수 vector<vector<int>> down(m+1,vector<int>(n+1,0)); // y행 x열에서 아래로 갈수있는 경우 수 //범위체크 힘드니깐 (1,1)부터 시작함 down[1][1]= 1; right[1][1]= 1; for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ if(i==1 && j == 1) continue; if(city_map[i-1][j-1] == 0){ right[i][j] = (right[i][j-1] + down[i-1][j]) % MOD; //왼쪽과 위쪽에서 온 값 합침 down[i][j] = (right[i][j-1] + down[i-1][j]) % MOD; } else if(city_map[i-1][j-1] == 2){ right[i][j] = right[i][j-1];//왼쪽에서 온값 down[i][j] = down[i-1][j];//위에서온값 } } } return down[m][n]; //맨 마지막 도착점의 city_map[][]은 0이여서, right[m][n]과 down[m][n]은 동일 }
+ 백준 내리막길 문제처럼 dfs를 이용한 dp를 사용할 경우
방향이 중요하므로 3차원 배열을 사용하면 된다 -> 처음에 2차원으로 고민하다보니 못했었다.
int dp[y][x][z] //y행 x열에서 z방향
for (int i = 0; i < 2; i++) { int ny = y + dy[i]; int nx = x + dx[i]; if (ny < 0 || ny >= m || nx < 0 || nx >= n || city_map[ny][nx] == 1 || (city_map[y][x] == 2 && i != dir)) { continue; } dp[y][x][dir] = ( dp[y][x][dir] + dfs(ny, nx, i, m, n, city_map) )% MOD; }
'문제 풀이' 카테고리의 다른 글
[프로그래머스] 점프와 순간이동 (0) 2020.06.02 [프로그래머스] 단체사진 찍기 (0) 2020.06.01 [프로그래머스] 최고의 집합 (0) 2020.05.31 [프로그래머스] 불량 사용자 (0) 2020.05.30 [프로그래머스] 길 찾기 게임 (0) 2020.05.30