티스토리 뷰

A] [징검다리 0] [징검다리 1] ... [징검다리 N-1] [B

철수는 다리가 짧아 징검다리를 한번에 한칸, 혹은 두칸만 건널 수 있다.
징검다리가 N개 있을때의 철수가 A에서 B로 이동할수 있는 경로의 수를 모두 구하라.

(아래 추가조건은 풀어도 되고, 안풀어도 되는 문제)
추가 조건1: '징검다리 p'는 너무 미끄러워 밟을 수 없다.
추가 조건2: 영희는 다리가 길어 징검다리를 한번에 한칸, 두칸, 혹은 세칸 건널 수 있다.

예(기본 문제 기준):

N == 0
A] [B
path 1: A -> B

N == 1
A] [징검다리 0] [B
path 1: A -> 0 -> B
path 2: A -> B

N == 2
A] [징검다리 0] [징검다리 1] [B
path 1: A -> 0 -> 1 -> B
path 2: A -> 1 -> B
path 3: A -> 0 -> B

예(추가조건 1기준):

N == 3, p == 2
A] [징검다리 0] [징검다리 1] [징검다리 2] [B
path 1: A -> 0 -> 1 -> B
path 2: A -> 1 -> B

징검다리 2가 미끄럽기때문에 2를 밟는 path인 0 -> 2, 1 -> 2, 2 -> B 가 불가능하다.


------------------------


일단 추가조건 없이 푸는 것은 일전에 풀었던 계단 올라가는 경우의 수와 비슷하게 재귀나 DP로 풀 수 있다.

N의 제한조건이 없지만, 가능경로의 수가 int 범위를 넘지 않기 위해서는 N<=30가 적절하다고 나름의 가정을 하겠다.


1
2
3
4
5
6
7
int steppingStone(int N) {
    if(N < 0return 0;
    if(N == 0return 1;
    if(N == 1return 2;
    
    return steppingStone(N-1+ steppingStone(N-2);
}

cs


코드로는 간단하지만, 이걸 이해하기 위해서는 트리와 재귀에 대한 기본적 지식이 필요하다.

이 설명을 능숙하게 하기 위해서는 앞으로 많은 연습이 필요할 듯 하다.


추가 조건1: '징검다리 p'는 너무 미끄러워 밟을 수 없다.

처음에 Brute force하게 작성한 코드는 기존과 같지만 현재 위치 앞 1칸 or 2칸에 '징검다리 p'가 존재하는지 여부에 대해 신경쓰면서 구현했다.


1
2
3
4
5
6
7
8
9
10
11
12
13
int ss1(int N,int p) {
    if(N < 0return 0;
    if(N == 0return 1;
 
    if(N == 1) {
        if(N-1 == p) return 1;
        else return 2;
    }
    
    if(N-1 == p) return ss1(N-2, p);
    if(N-2 == p) return ss1(N-1, p);
    return ss1(N-1,p) + ss1(N-2,p);
}

cs

그런데 생각해보니 철수는 다리가 짧아 최대 두칸밖에 가지 못하므로 징검다리 p를 피해 건너는 방법은 한가지 뿐이다.

ㄱ. 징검다리 p가 철수 앞 어딘가에 있다면

ㄴ. A에서 '징검다리 p-1'까지 이동한다. (처음의 steppingStone 함수를 이용)

ㄷ. '징검다리 p-1'에서 한번에 두칸을 건너 '징검다리 p+1'로 이동한다.

ㄹ. B까지 이동한다. (처음의 steppingStone 함수를 이용)

하면 아래와 같은 코드가 작성된다.

1
2
3
4
5
6
7
8
9
int addition(int N, int p) {
    int frontP = steppingStone(p-1);
    int backP = steppingStone(steppingStone((N-1)-(p+1)));
    
    if(frontP == 0) frontP = 1;
    if(backP == 0) backP = 1;
    
    return (frontP * backP);
}
cs

이렇게 한다면, 시간복잡도는 다르지 않겠지만 좀 더 이해하기 쉽고, 가독성이 좋은 함수를 작성할 수 있다.


테스트 결과 아래와 같다.

답이 없어서 채점도 못해봤다. 추가조건2는 다음에 시간날 때 풀어야겠다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main() {
    
    int N;
    int p;
    
    //추가조건 없이
    cin >> N;                            // 20
    cout << steppingStone(N) << endl;    // 17711
    
    // 추가조건1 bruteForce ver
    cin >> N >> p;                        // 20 13
    cout << ss1(N, p) << endl;            // 4901
    
    // 추가조건1 간략화 버전
    cin >> N >> p;                        // 20 13
    cout << addition(N, p) << endl;        // 4901
    return 0;
    
}

cs



공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/11   »
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
글 보관함