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

 

이번에 볼 문제는 백준 1593번 문제인 문자 해독이다.
문제는 아래 링크를 확인하자.

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

 

1593번: 문자 해독

첫째 줄에 고고학자들이 찾고자 하는 단어 W의 길이 g와 발굴된 벽화에서 추출한 문자열 S의 길이 |S|가 빈 칸을 사이에 두고 주어진다. (1≤g≤3000,  g≤|S|≤3,000,000) 둘째 줄에 W, 셋째 줄에 S의 실

www.acmicpc.net

찾고자 하는 단어를 W라 하고, W를 찾으려는 문자열을 S라 하자.

이 문제는 S의 각 W길이의 부분문자열에 포함된 문자구성이 W와의 문자구성과 같은지를 판단하는 문제이다.

 

[a,b] 구간의 부분문자열의 구성과 [a+1,b+1] 구간의 부분문자열 구성을 살펴보자.

두 문자를 제외하고 모두 일치한다는 것을 알 수 있다.

그렇다는 것은, 문자구성을 계산할 때 중복된 부분에 대한 작업을 새로 하지 않고 재활용할 수 있는 방식을 떠올린다면 이 문제를 쉽게 해결할 수 있다는 뜻이 된다.

 

글쓴이는 각 W의 길이 부분문자열에 대하여 불일치도 chk를 만들어 점화식을 세워 문제를 풀었다.

 

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

#include <iostream>
#include <string>
using namespace std;

int cnt[128];

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

	int s1len, s2len; cin >> s1len >> s2len;

	string s1, s2; cin >> s1 >> s2;
	for (int i = 0; i < s1len; i++) cnt[s1[i]]++;

	int chk = s1len, ans = 0; // chk: 현재 불일치도
	for (int i = 0; i < s1len; i++) {
		if (cnt[s2[i]] > 0) chk--;
		else chk++;
		cnt[s2[i]]--;
	}
	if (chk == 0) ans++;

	for (int i = s1len; i < s2len; i++) {
		int L = i - s1len;
		if (cnt[s2[L]] < 0) chk--;
		else chk++;
		cnt[s2[L]]++;

		if (cnt[s2[i]] > 0) chk--;
		else chk++;
		cnt[s2[i]]--;

		if (chk == 0) ans++;
	}

	cout << ans;
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 1043 // C++] 거짓말  (0) 2021.06.04
[BOJ 1208 // C++] 부분수열의 합 2  (0) 2021.06.03
[BOJ 5054 // C++] 주차의 신  (0) 2021.06.01
[BOJ 10807 // C++] 개수 세기  (0) 2021.06.01
[BOJ 11098 // C++] 첼시를 도와줘!  (0) 2021.06.01

+ Recent posts