문제 링크 : https://programmers.co.kr/learn/courses/30/lessons/1832
문제를 읽어보니 순간 두 가지 방법이 떠올랐다.-> dfs,bfs를 이용하는 방법, dp를 이용하는 방법.
이차원배열의 크기가 500*500=250000되는 것만 보아도 dfs,bfs를 이용하면 시간초과를 훌쩍 넘길 것을 예상할 수 있다.
게다가 20170805으로 나눈 나머지값을 리턴하라는 것만 보아도 시간초과를 예상할 수 있다.
당연히 방법은 dp를 사용하여야 한다.
<전체적인 알고리즘>
1. 배열은 이차원이라 d[502][502] 를 선언해야 하지만 각 위치마다 위에서 내려온 경로, 왼쪽에서 온 경로 두가지를 나눠 저장해야 했기때문에 d[502][502][2]를 선언하였다. 0은 위에서 온 경우,, 1은 왼쪽에서 온 경우로 정했다.
(city_map배열에서 도로가 2인경우는 그 방향대로 통과해야했기에 위에서 온 경로, 왼쪽에서 온 경로 따로 저장하였다.)
2. 기본원리를 생각하면 해당 위치의 경로 개수는 위칸의 경로 개수 + 왼쪽칸의 경로 개수이다. 하지만 위칸이 2일경우에는 위칸의 위칸에서 내려온 경우만 통과하기 때문에 그 경우, 위칸에서 내려온 경로개수는 위칸의 위칸에서 내려온 경로 개수가 된다. 왼쪽에서 온 경로도 마찬가지로 생각하면 된다.
3. 결국 최종 개수는 m행 n열 칸의 위쪽에서 내려온 경로 수+왼쪽에서 온 경로 수 가 된다.
(물론 20170805로 mod연산 해주는 것을 잊지 말자)
#include<iostream>
#include <vector>
using namespace std;
int MOD = 20170805;
// 전역 변수를 정의할 경우 함수 내에 초기화 코드를 꼭 작성해주세요.
int solution(int m, int n, vector<vector<int>> city_map) {
int d[502][502][2]; //3차 index가 0 -> 위쪽에서 온 경우 // 1 -> 왼쪽에서 온 경우
fill(&d[0][0][0],&d[499][499][2],0);
d[0][0][0] = 1; //이거 대신에 d[0][0][1]을 1로 세팅해도됨.
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
if (city_map[i][j] == 1)continue;
if (j > 0 && city_map[i][j - 1] == 2) //위칸이 존재하며 2일 때
{
d[i][j][1] = d[i][j - 1][1];
}
else if(j>0) // 위칸이 존재하며 위칸이 0일 때
{
d[i][j][1] = (d[i][j - 1][0] + d[i][j - 1][1]) % MOD;
}
if (i > 0 && city_map[i - 1][j] == 2) //왼쪽 칸이 존재하며 2일 때
{
d[i][j][0] = d[i - 1][j][0];
}
else if(i>0) //왼쪽 칸이 존재하며 0일때
{
d[i][j][0] = (d[i - 1][j][0] + d[i - 1][j][1]) % MOD;
}
}
}
int answer = (d[m - 1][n - 1][0] + d[m - 1][n - 1][1])%MOD;
return answer;
}
궁금하신 점은 댓글에 남겨주시면 답변드리겠습니다.
'프로그래머스 코딩 문제 > 카카오 기출문제' 카테고리의 다른 글
[프로그래머스] 프렌즈4블록 (2018 KAKAO BLIND RECRUITMENT) (0) | 2020.08.31 |
---|---|
[프로그래머스] 괄호 변환 (2020 KAKAO BLIND RECRUITMENT) (0) | 2020.08.30 |
[프로그래머스] 단체사진 찍기 (2017 카카오코드 본선) (level 3) (0) | 2020.08.28 |
[프로그래머스] 카카오 프렌즈 컬러링북 (2017 카카오코드 예선) (0) | 2020.08.26 |
[프로그래머스] 문자열 압축 (2020 KAKAO BLIND RECRUITMENT) (0) | 2020.08.19 |