※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 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 |