백준 12904 - A와 B
1 minute read
문제링크
문제설명
- A와 B로만 이루어진 문자열 S와 T가 주어진다.
- 다음과 같은 2가지 규칙만을 이용하여 S를 T로 바꿀 수 있는지 알아내는 프로그램을 작성하라.
- 문자열의 뒤에 A를 추가한다.
- 문자열을 뒤집고 뒤에 B를 추가한다.
문제접근
- 처음에는 재귀호출을 통해 S -> T 를 만들어가도록 하였다. 즉, 완전탐색으로 풀려고 했었는데 시간초과에 걸렸다.
- 두번째는 그리디에서 힌트를 얻었고, 두가지 규칙을 살펴본 후 T -> S 로 한가지 루트를 통해서 탐색이 가능한 것을 알았다.
- 만약 T의 마지막 문자가 A라면 1번 규칙에서 파생되었을 것이다.
- 만약 T의 마지막 문자가 B라면 2번 규칙에서 파생되었을 것이다.
- 위 방법으로 T가 되기 이전의 글자를 만들어가면서 S와 길이가 같아졌을 때, 동일한 문자열인지의 여부로 정답을 출력한다.
구현 (그리디)
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
cin.tie(NULL);
ios_base::sync_with_stdio(false);
string S, T;
cin >> S >> T;
string tmp = T;
while (tmp.length() != S.length()) {
if (tmp.back() == 'A') tmp.pop_back();
else if (tmp.back() == 'B') {
tmp.pop_back();
reverse(tmp.begin(), tmp.end());
}
}
if (tmp != S) printf("0\n");
else printf("1\n");
}
구현 (재귀 - 시간초과)
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
string S, T;
void addA() {
S += "A";
}
void removeA() {
S.pop_back();
}
void addB() {
reverse(S.begin(), S.end());
S += "B";
}
void removeB() {
S.pop_back();
reverse(S.begin(), S.end());
}
bool makeStoT() {
if (S.length() == T.length()) {
if (S == T) return true;
else return false;
}
bool ret = false;
for (int i = 0; i < 2; i++) {
if (i == 0) {
addA();
ret = ret | makeStoT();
if (ret) return true;
removeA();
}
else {
addB();
ret = ret | makeStoT();
if (ret) return true;
removeB();
}
}
return ret;
}
int main()
{
cin.tie(NULL);
ios_base::sync_with_stdio(false);
cin >> S >> T;
int ans = (int)makeStoT();
printf("%d\n", ans);
return 0;
}
Leave a comment