BOJ 1342

행운의문자열

문제출처

문제 해석

  • 인접한 알파벳이 서로 다른 문자열을 행운의 숫자라고 하는데, 주어진 문자열을 조합하여 행운의 숫자를 만들 수 있는 경우의 수를 찾는 문제입니다.

설계(5)

  • 문자열의 길이(<=10)가 길지 않으므로 완전탐색을 하면 됩니다.
  • 편의성을 위해서 각 알파벳이 들어있는 개수를 저장한 후, 벡터에 해당 알파벳과 보유 숫자를 저장해 놓습니다.
  • 백트래킹을 이용해서 모든 경우의 수를 조사합니다.

구현(5)

코드
#include <iostream>
#include <vector>
using namespace std;

int num[26];
int len;
int ans = 0;
vector<pair<int, int> > v;
void dfs(int depth, int prev) {
	if (depth == len) {
		ans++;
		return;
	}
	for (int i = 0; i < v.size(); i++) {
		if (v[i].second == 0) continue;
		if (v[i].first != prev) {
			v[i].second--;
			dfs(depth + 1, v[i].first);
			v[i].second++;
		}
	}
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	string s;
	cin >> s;
	len = s.length();
	for (int i = 0; i < s.length(); i++) {
		num[s[i] - 'a']++;
	}
	for (int i = 0; i < 26; i++) {
		if (num[i] == 0) continue;
		v.push_back({ i,num[i] });
	}
	dfs(0,-1);
	cout << ans << "\n";
	return 0;
}
디버깅
  • 처음에는 num[26]배열을 for문에 돌게 하였지만, 탐색 속도를 조금 더 빠르게 하기 위해서 별도로 벡터에 저장을 한 후 탐색하도록 하였습니다.
제출결과
  • 136ms

마무리

  • 단순 백트래킹 문제였습니다. 백준 solved.ac 기반 난이도가 GOLD3으로 되어있으나, 이정도의 난이도는 아닌 것 같습니다.