pstopia Notes for Problem Solving Contest

[C] Anagram Search

Codeforces Round #103 (Div. 2)

Problem

anagram 인지를 확인하면 되므로 문자열 매칭을 할 필요는 없고, 알파벳 별 개수만 갖고 확인할 수 있다. sliding window 로 문자열p를 문자열s의 처음부터 대조하면서 오른쪽으로 나아가면 된다. 현재 s_i = s[i..i+|p|-1] 을 대조하고 있다고 했을 때 count(p, c) > count(s_i, c) 인 알파벳 c가 존재한다면 그 부분은 anagram이 될 가능성이 없는 것이다. 만약 이렇지 않다면 '?'를 적절히 치환하여 anagram으로 항상 만들 수 있다. window를 오른쪽으로 한칸 옮길 때 count 함수를 일일히 갱신하는 것이 아니라 방금 window에서 빠지게 된 문자, 방금 window로 들어오게 된 문자 두가지만 +-1 을 해주면 된다.
#include <cstdio>
#include <vector>
#include <string>
using namespace std;
char buf[100005];
int main() {
scanf("%s", buf);
string s(buf);
scanf("%s", buf);
string p(buf);
vector<int> pcnt(26);
for (char c : p) pcnt[c - 'a'] += 1;
int ans = 0;
vector<int> nowcnt(26);
for (int i = 0, j = 0; i + p.length() <= s.length(); ++i) {
while (j < i + p.length()) {
if (s[j] != '?') nowcnt[s[j] - 'a'] += 1;
++j;
}
bool ok = true;
for (int k = 0; k < 26; ++k) {
if (pcnt[k] < nowcnt[k]) {
ok = false;
break;
}
}
if (ok) ans += 1;
if (s[i] != '?') nowcnt[s[i] - 'a'] -= 1;
}
printf("%d\n", ans);
return 0;
}
view raw cf103c.cpp hosted with ❤ by GitHub