※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 2079번 문제인 팰린드롬이다.
문제는 아래 링크를 확인하자.

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

 

2079번: 팰린드롬

첫째 줄에 단어가 입력으로 들어온다. 단어는 영어 소문자로만 이루어져 있으며, 그 길이는 2,000을 넘지 않는다.

www.acmicpc.net

모든 팰린드롬 문자열은 그 길이가 3 이상이라면 양 끝의 두 문자를 지워도 다시 팰린드롬 문자열이 됨을 상기하자.

 

따라서, 가운데를 담당할 문자 하나 또는 둘을 먼저 고르고 양 옆에 문자를 하나씩 이어나가 팰린드롬 성질이 깨질 때까지 살피는 것으로 주어진 문자열에 존재하는 모든 팰린드롬 문자열에 한번씩 접근할 수 있게 된다.

 

dp[j]를 주어진 문자열의 [0,j] 구간에 해당하는 부분문자열에 대하여 이를 최소 개수의 팰린드롬으로 분할할 때의 개수라 하면 이는 [i,j] 구간에 해당하는 부분무자열이 팰린드롬인 모든 i에 대하여 dp[i - 1] + 1의 최솟값으로 계산할 수 있음을 관찰하자.

 

위의 관계를 인덱스를 노드, [i,j] 구간을 i에서 j+1로 향하는 에지로 하는 그래프로 모델링하자. 이 때 주어진 문제는 0번 인덱스에서 (문자열의 길이)번 인덱스까지 향하는 최단거리 문제로 바꾸어 생각할 수 있게 된다. BFS 등을 이용해 해당하는 최단거리를 구하고 문제를 해결하자.

 

아래는 제출한 소스코드이다.

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

string s; int slen;
vector<int> G[2001];
int dist[2001];

void bfs() {
	queue<int> que;
	que.push(0);

	while (!que.empty()) {
		int cur = que.front(); que.pop();
		for (auto& nxt : G[cur]) {
			if (dist[nxt]) continue;
			dist[nxt] = dist[cur] + 1;
			que.push(nxt);
		}
	}
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> s; slen = s.length();
	for (int mid = 0; mid < slen; mid++) { // 홀수길이 팰린드롬
		int L = mid, R = mid;
		while (-1 < L && R < slen && s[L] == s[R]) {
			G[L].emplace_back(R + 1);
			L--, R++;
		}
	}
	for (int midL = 0, midR = 1; midR < slen; midL++, midR++) { // 짝수길이 팰린드롬
		int L = midL, R = midR;
		while (-1 < L && R < slen && s[L] == s[R]) {
			G[L].emplace_back(R + 1);
			L--, R++;
		}
	}

	bfs();

	cout << dist[slen];
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 3277 // C++] DOMAINS  (0) 2023.08.29
[BOJ 2082 // C++] 시계  (0) 2023.08.28
[BOJ 3279 // C++] DOLLARS  (0) 2023.08.26
[BOJ 3284 // C++] MASS  (0) 2023.08.25
[BOJ 3283 // C++] BARCODE  (0) 2023.08.24

+ Recent posts