Posts 백준 9177 단어 섞기 c++
Post
Cancel

백준 9177 단어 섞기 c++

문제

https://www.acmicpc.net/problem/9177

문제해설

n개의 데이터셋이 주어진다.
각 데이터에는 문자열 3개가 들어있다.
첫번째와 두번째 문자열을 섞어 세번째 문자열을 만들 수 있는지 판별하면 된다.
섞는 방법은 두 문자열을 합치며 각각 문자열의 순서는 바뀌면 안된다.
문제의 예시를 보면
cat과 tree를 이용해 tcraete는 만들 수 있지만
cttaree는 만들 수 없다.
만들 수 있는 문자열이면 yes를 그렇지 않다면 no를 출력해주면 된다.

문제풀이

dfs를 이용해서 해결했다.
문제를 고민해보니 백트래킹을 이용해야겠다는 생각이 들었다.

1
2
3
4
if (a[a_idx] == res[len])
	dfs(a_idx + 1, b_idx, len + 1);
if (b[b_idx] == res[len])
	dfs(a_idx, b_idx + 1, len + 1);

위 코드처럼 조건을 만족한다면 인덱스를 증가시키며 재귀함수를 호출하고
그렇게 증가한 길이가 세번째 문자열의 길이와 같아진다면 yes라고 판단해주었다.

하지만 재귀로만 짰을 때 시간초과가 생겼다.
왜 그런지 찾아보니 세번째 문자열에 첫번째와 두번째에 포함되지않는
새로운 문자가 들어올 수 있어 그 경우에 시간이 많이 소요되는 것으로 보였다.

그래서 test()라는 함수를 만들어
포함되지 않는 새로운 문자열이 있거나 길이가 다르다면
바로 no를 출력할 수 있게 만들어 주었더니 맞았다.

전체코드

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
string a, b, res;
bool find_flag;
int aLen, bLen, resLen;

bool test() {
	vector<int>alp(27, 0);
	for (int i = 0; i < aLen; i++)
		alp[a[i] - 'a']++;
	for (int i = 0; i < bLen; i++)
		alp[b[i] - 'a']++;
	for (int i = 0; i < resLen; i++)
		alp[res[i] - 'a']--;
	bool flag = false;
	for (int i = 0; i < 26; i++) {
		if (alp[i] != 0)
			flag = true;
	}
	if (flag)
		return false;
	else
		return true;
}

void dfs(int a_idx, int b_idx, int len) {
	if (find_flag)
		return;
	if (len == resLen) {
		find_flag = true;
		return;
	}
	if (a[a_idx] == res[len])
		dfs(a_idx + 1, b_idx, len + 1);
	if (b[b_idx] == res[len])
		dfs(a_idx, b_idx + 1, len + 1);
}

int main() {
	ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
	int n; cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a >> b >> res;
		find_flag = false;
		aLen = a.length(); bLen = b.length();
		resLen = res.length();
		cout << "Data set " << i << ": ";
		if (test())
			dfs(0, 0, 0);
		if (find_flag)
			cout << "yes\n";
		else
			cout << "no\n";
	}
	return 0;
}

sync_with_stdio(false) cin.tie(NULL) cout.tie(NULL)

백준 10252 그리디 그래프 c++

Comments powered by Disqus.