(백준/C++) 16139_인간-컴퓨터 상호작용
개요
16139번: 인간-컴퓨터 상호작용 (acmicpc.net) 문제는 특정 문자열 내에서 주어진 구간에 특정 알파벳이 몇 번 나타나는지 빠르게 구하는 문제로 누적 합 문제 카테고리에 속해 있습니다.
누적 합 문제는 구간에 있는 수의 합을 빠르게 계산하기 위한 방법입니다.
이게 왜 누적 합 문제인지 헷갈릴 수도 있지만, 알파벳이 나타나는 횟수를 물어보기 때문에, 그 횟수가 누적된다고 보시면 이해하기 쉬울 것 같습니다.
이 문제는 $O(26 \cdot N)$의 시간 복잡도로 누적 합 배열을 생성하고, 특정 구간의 횟수를 $O(1)$의 시간 복잡도로 구할 수 있습니다.
로직 설계
이 문제는 각 알파벳별로 특정 구간의 출현 횟수를 빠르게 구해야 하므로, 알파벳별로 누적 합을 저장하는 방법으로 해결할 수 있습니다.
만약 이 문제가 이해가 어려우시다면 11659번: 구간 합 구하기 4 (acmicpc.net) 문제를 먼저 푸시는 것을 추천 드립니다.
관련 포스트 - (백준/C++) 구간 합 구하기 4 풀이
풀이
누적 합을 이용하여 주어진 구간의 특정 알파벳의 출현 횟수를 계산하기 위해서는 문자열을 순회하며 각 알파벳별로 누적 합을 저장하면 됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
int q;
string str;
cin >> str;
cin >> q;
vector<vector<int>> alphabet(str.length() + 1, vector<int>(26, 0));
//누적합 배열 계산
for (int i = 0; i < str.length(); i++)
{
for (int j = 0; j < 26; j++)
{
alphabet[i + 1][j] = alphabet[i][j]; //기존 알파벳 누적합 유지
}
alphabet[i + 1][str[i] - 'a']++; //추가된 알파벳 누적합 추가
}
while (q--)
{
char alpha;
int s, e;
cin >> alpha >> s >> e;
//해당 알파벳의 누적합 구간 출력
cout << alphabet[e + 1][alpha - 'a'] - alphabet[s][alpha - 'a'] << '\n';
}
}
이 기사는 저작권자의 CC BY-NC-ND 4.0 라이센스를 따릅니다.