새소식

PS/백준

[백준/2602] 돌다리 건너기 (Python)

  • -

 

Problem : https://www.acmicpc.net/problem/2602

 

2602번: 돌다리 건너기

첫째 줄에는 마법의 두루마리에 적힌 문자열(R, I, N, G, S 로만 구성된)이 주어진다. 이 문자열의 길이는 최소 1, 최대 20 이다. 그 다음 줄에는 각각 <악마의 돌다리>와 <천사의 돌다리>를 나타내는

www.acmicpc.net

 

Difficulty : Gold 4

 

Status : Solved

 

Time : 00:10:13

 


 

문제 설명

 

더보기

절대반지를 얻기 위하여 반지원정대가 출발한다. 원정대가 지나가야할 다리는 두 개의 인접한 돌다리로 구성되어 있다. 하나는 <악마의 돌다리>이고 다른 하나는 <천사의 돌다리>이다.

아래 그림 1은 길이가 6인 다리의 한 가지 모습을 보여준다. 그림에서 위의 가로줄은 <악마의 돌다리>를 표시하는 것이고, 아래의 가로줄은 <천사의 돌다리>를 표시한다. 두 돌다리의 길이는 항상 동일하며, 각 칸의 문자는 해당 돌에 새겨진 문자를 나타낸다. 두 다리에 새겨진 각 문자는 {R, I, N, G, S} 중 하나이다.

 

 

반지원정대가 소유하고 있는 마법의 두루마리에 <악마의 돌다리>와 <천사의 돌다리>를 건너갈 때 반드시 순서대로 밟고 지나가야할 문자들이 적혀있다. 이 순서대로 지나가지 않으면 돌다리는 무너져 반지원정대는 화산 속으로 떨어지게 된다.

다리를 건널 때 다음의 제한 조건을 모두 만족하면서 건너야 한다.

  1. 왼쪽(출발지역)에서 오른쪽(도착지역)으로 다리를 지나가야 하며, 반드시 마법의 두루마리에 적힌 문자열의 순서대로 모두 밟고 지나가야 한다.
  2. 반드시 <악마의 돌다리>와 <천사의 돌다리>를 번갈아가면서 돌을 밟아야 한다. 단, 출발은 어떤 돌다리에서 시작해도 된다.
  3. 반드시 한 칸 이상 오른쪽으로 전진해야하며, 건너뛰는 칸의 수에는 상관이 없다. 만일 돌다리의 모양이 그림 1과 같고 두루마리의 문자열이 "RGS"라면 돌다리를 건너갈 수 있는 경우는 다음의 3가지 뿐이다. (아래 그림에서 빨간색 문자는 밟고 지나가는 돌다리를 나타낸다.)

아래의 세 방법은 실패한 방법이다.

왜냐하면 첫 번째는 문자열 "RGS"를 모두 밟고 지나가야 하는 조건 1)을 만족하지 않으며, 두 번째는 번갈아가면서 돌을 밟아야 하는 조건 2)를, 세 번째는 앞으로 전진을 하여야하는 조건 3)을 만족하지 않기 때문이다.

마법의 두루마리에 적힌 문자열과 두 다리의 돌에 새겨진 문자열이 주어졌을 때, 돌다리를 통과할 수 있는 모든 가능한 방법의 수를 계산하는 프로그램을 작성하시오. 예를 들어, 그림 1의 경우는 통과하는 방법이 3가지가 있으므로 3을 출력해야 한다.

 

입력 및 출력

 

더보기

입력

첫째 줄에는 마법의 두루마리에 적힌 문자열(R, I, N, G, S 로만 구성된)이 주어진다. 이 문자열의 길이는 최소 1, 최대 20 이다. 그 다음 줄에는 각각 <악마의 돌다리>와 <천사의 돌다리>를 나타내는 같은 길이의 문자열이 주어진다. 그 길이는 1 이상, 100 이하이다.

 

출력

마법의 두루마리에 적힌 문자열의 순서대로 다리를 건너갈 수 있는 방법의 수를 출력한다. 그러한 방법이 없으면 0을 출력한다.

모든 테스트 데이터에 대한 출력결과는 2^31-1 이하이다.

 

입력 예시

RGS
RINGSR
GRGGNS

 

출력 예시

3

 

 


 

풀이

 

간단한 종류의 DP 문제. 앞서 오늘 풀이했던 문제에서 깨진 멘탈을 추스리기 위해 도전하였다. ㅠㅠ

 

2023.03.17 - [알고리즘 문제/백준] - [백준/2598] 기둥만들기 (Python)

 

[백준/2598] 기둥만들기 (Python)

Problem : https://www.acmicpc.net/problem/2598 2598번: 기둥만들기 첫줄에는 1번 정육면체, 두 번째 줄에 2번 정육면체, 세 번째 줄에 3번 정육면체, 네 번째 줄에 4번 정육면체가 입력된다. 각 줄은 6개의 영문

magentino.tistory.com

 

k번째 돌다리의 i번째 좌표가 j번째 글자와 일치할 때, 우리는 (1-k)번째 돌다리의 0부터 (i-1)번째 좌표 중 (j-1)번째 글자를 밟는 경우의 수를 모두 더하여 구할 수 있다.

 

DP[i][j][k] = sum( DP[0][j-1][1-k], ... , DP[i-1][j-1][1-k] )

 

초기값은 모든 돌다리 중 맨 처음 글자를 포함하는 돌다리에 한해 1로 초기화해주면 된다.

 

  • make_dp : 앞선 점화식대로 dp 리스트를 작성하는 함수. dp 리스트를 반환한다.
  • find_result : dp 리스트에서 글자 중 마지막 글자에 해당하는 값들을 더하여 반환하는 함수.
  • solve : 메인함수. find_result에서 반환받은 정답을 출력한다.

 

 

 

풀이 코드

 


order_list = input().strip()
board_list = [input().strip() for _ in range(2)]

order_len = len(order_list)
board_len = len(board_list[0])

def make_dp() :
  dp = [[[0]*2 for _ in range(order_len)] for _ in range(board_len)]

  for i in range(board_len) :
    for j in range(order_len) :
      for k in range(2) :
        if board_list[k][i] == order_list[j] :
          if j == 0 :
            dp[i][j][k] = 1
          else :
            for l in range(i) :
              dp[i][j][k] += dp[l][j-1][1-k]

  return dp

def find_result(dp) :
  result = 0
  for i in range(board_len) :
    for j in range(2) :
      result += dp[i][-1][j]

  return result

def solve() :
  dp = make_dp()
  result = find_result(dp)

  print(result)

solve()

풀이 완료~

 

'PS > 백준' 카테고리의 다른 글

[백준/2635] 수 이어가기 (Python)  (4) 2023.03.19
[백준/8979] 올림픽(Python)  (0) 2023.03.18
[백준/2598] 기둥만들기 (Python)  (0) 2023.03.17
[백준/10165] 버스 노선 (Python)  (0) 2023.03.16
[백준/2573] 빙산 (Python)  (0) 2023.03.15
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.