본문 바로가기
알고리즘/C++

[백준] 23564 - 재귀 문자열 by C++

by 엑츄얼리 2023. 1. 27.

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

 

23564번: 재귀 문자열

$(c, \{7\}), (cc, \{1,3\}), (ccc, \{1,1,1\})$ 등이 모두 정답이다.

www.acmicpc.net

최근들어 제일 오래걸린 문제였다....

오늘따라 머리가 안굴러가긴했는데,

그렇다보니 잘못된 방식 고집하면서 날린 시간도 너무 길었다.

아닌 것 같으면 다른 방식 생각해보는 습관도 가지자....

 

알고리즘 방식

X1 = s1...s1

X2 = [s1...s1]s2...[s1...s1]

X3 = {[s1...s1]s2...[s1...s1]}s3{[s1...s1]s2...[s1...s1]}

X1, X2, X3를 각각 풀어서 작성하면 위와 같다.

이를 기반으로 X3를 통해 S, A 집합을 구할 수 있다.

 

이 문제는 X3 문자열을 앞에서부터 접근하면서 

위의 X3과 예제의 X을 통해 이해할 수 있다.

X = aabaabaacaabaabaa

1. 제일 앞의 a는 s1임을 알 수 있다.
2. 처음으로 나오는 a와 다른 문자인 b는 s2가 되고,
    그 직전까지의 문자열은 X1 = aa이 된다. (a1=2확인 가능)

위 2개의 정보를 통해 X2 = aabaabaa도 확인할 수 있다. (a2=2확인 가능)

이를 기반으로 어떤 문자열이 입력되더라도
S와 A 집합을 채울 수 있다.

 

소스코드

#include <iostream>
#include <vector>
#include <string>

using namespace std;

string inp;
int inpLen;
vector<char> S;
vector<int> A;

void func(string x, int n) {
	int len = x.size();
	
	char s;
	int a = 0;
	int cur = len;

	if (n == 1) {
		for (int i = 0; i < inpLen; i++) {
			if (inp[i] == x[0])
				a++;
			else
				break;
		}
		S.push_back(x[0]);
		A.push_back(a);
		
		if (a == inpLen)
			return;

		func(inp.substr(0, a), n + 1);
	}

	else {
		s = inp[len];

		while (cur < inpLen) {
			if (s == inp[cur])
				a++;
			else {
				S.push_back(s);
				A.push_back(a);
				func(inp.substr(0, cur), n + 1);
				return;
			}
			cur += len + 1;
		}
		S.push_back(s);
		A.push_back(a);
		return;
	}
}

int main(void) {
	ios::sync_with_stdio(false);
	cin.tie(NULL);

	cin >> inp;
	inpLen = inp.size();
	func(inp.substr(0, 1), 1);

	for (auto x : S)
		cout << x;
	cout << '\n';
	for (auto x : A)
		cout << x << ' ';
}

 

'알고리즘 > C++' 카테고리의 다른 글

[백준] 13414 - 수강신청 by C++  (0) 2023.06.14
[백준] 1261 - 알고스팟 by C++  (0) 2023.03.24
[백준] 11265 - 끝나지 않는 파티  (0) 2023.01.20
[백준] 1520 - 내리막 길  (0) 2023.01.09
[백준] 18870 - 좌표 압축  (0) 2022.12.30

댓글