문제
수빈이는 A와 B로만 이루어진 영어 단어 존재한다는 사실에 놀랐다. 대표적인 예로 AB (Abdominal의 약자), BAA (양의 울음 소리), AA (용암의 종류), ABBA (스웨덴 팝 그룹)이 있다.
이런 사실에 놀란 수빈이는 간단한 게임을 만들기로 했다. 두 문자열 S와 T가 주어졌을 때, S를 T로 바꾸는 게임이다. 문자열을 바꿀 때는 다음과 같은 두 가지 연산만 가능하다.
- 문자열의 뒤에 A를 추가한다.
- 문자열의 뒤에 B를 추가하고 문자열을 뒤집는다.
주어진 조건을 이용해서 S를 T로 만들 수 있는지 없는지 알아내는 프로그램을 작성하시오.
입력
첫째 줄에 S가 둘째 줄에 T가 주어진다. (1 ≤ S의 길이 ≤ 49, 2 ≤ T의 길이 ≤ 50, S의 길이 < T의 길이)
출력
S를 T로 바꿀 수 있으면 1을 없으면 0을 출력한다.
예제 입력 1
A
BABA
예제 출력 1
1
예제 입력 2
BAAAAABAA
BAABAAAAAB
예제 출력 2
1
예제 입력 3
A
ABBA
예제 출력 3
0
이 문제는 12904번(A와 B)과 비슷해 보이지만, 차이점이 하나 있어서 그리디(Greedy)방식으로는 풀 수 없고 DFS 나 완전 탐색을 써야 하는 문제입니다.
왜 12904번 방식으로는 안 될까?
12904번 문제는 문자열 의 맨 뒤만 보면 어떤 연산을 해서 왔는지가 확실했습니다.
- 맨 뒤가 A면? A 추가 연산임.
- 맨 뒤가 B면? 뒤집고 B 추가 연산임.
하지만 12919번(A와 B 2)은 다릅니다. 에서 로 돌아가는 역연산을 생각해보면
- 규칙 1 역연산: 의 맨 뒤가 A라면 A를 뗀다.
- 규칙 2 역연산: 의 맨 앞이 B라면 B를 떼고 뒤집는다. (문제 조건: 뒤에 B를 추가하고 뒤집는다 결과물은 무조건 B로 시작한다는 말)
문제 상황: 만약 가 "B.....A" 형태라면?
- 경우 1: 맨 뒤가 A니까 A를 떼도 됩니다.
- 경우 2: 맨 앞이 B니까 B를 떼고 뒤집어도 됩니다.
두 가지 경우의 수가 모두 가능하기 때문에, 둘 중 어느 길이 정답으로 가는 길인지 지금 당장은 알 수 없기 때문에 그래서 단순히 반복문으로 구하기는 어렵습니다.
해결 방법 : 재귀를 이용한 DFS
에서 시작해서 를 만들 수 있는지 확인합니다.
- 현재 문자열의 길이가 와 같아지면? 와 같은지 비교하고 결과 반환.
- 끝이 A라면? A를 떼고 재귀 호출.
- 시작이 B라면? B를 떼고 뒤집어서 재귀 호출.
- 둘 다 해당되면? 둘 다 해봄.
코드
import sys
# 입력 받기
S = sys.stdin.readline().rstrip()
T = sys.stdin.readline().rstrip()
def solve(t):
# 1. 종료 조건: 현재 문자열 t의 길이가 S와 같아지면 비교
if len(t) == len(S):
return t == S
# 2. 재귀 호출 (두 가지 경우를 모두 확인)
# Case 1: t의 맨 뒤가 'A'인 경우 -> A를 제거하고 계속 탐색
if t[-1] == 'A':
# 재귀 호출한 결과가 True라면(성공했다면) 즉시 True 반환
if solve(t[:-1]):
return True
# Case 2: t의 맨 앞이 'B'인 경우 -> B를 제거하고 뒤집어서 계속 탐색
# (문제의 연산: B추가 -> 뒤집기 / 역연산: B제거(앞에서) -> 뒤집기)
if t[0] == 'B':
# t[1:]은 맨 앞 글자 제거, [::-1]은 뒤집기
if solve(t[1:][::-1]):
return True
# 모든 시도가 실패하면 False
return False
# 함수 실행 및 결과 출력
if solve(T):
print(1)
else:
print(0)
'백준' 카테고리의 다른 글
| [프로그래머스] N-Queen (0) | 2026.02.07 |
|---|---|
| [프로그래머스] 등굣길 (0) | 2026.02.05 |
| [백준] 12904번 - A와 B (0) | 2026.02.05 |
| [백준] 7490번 - 0만들기 (0) | 2026.02.04 |
| [백준] 2531번 - 회전초밥 (0) | 2026.02.04 |