문제 링크
- http://icpc.me/10840
문제 출처
- 2015 KOI 전국 본선 고등부2
사용 알고리즘
- Hash
시간복잡도
- 평균 O(N2 + M2)
풀이
가장 Naive한 풀이는 모든 경우를 단순 for문으로 돌려보는 것이고, O(N2M2)정도 걸립니다.
N과 M 모두 최대 1500이기 때문에 조금 더 효율적인 방법을 생각해봅시다.
특정 구간에 알파벳들이 각각 몇 개씩 있는지를 판단하는 것이 핵심입니다. 각각의 알파벳을 서로 다른 소수와 매칭을 시킨 뒤, 구간에 속해있는 알파벳에 따라 곱해주는 방식의 해시를 사용하면 쉽게 풀릴 것 같습니다. 바로 구현을 해봅시다.
소수를 적당한 개수만큼 구합시다.
1 |
|
소수를 최대 1500개를 곱해야 합니다. 숫자가 너무 커지기 때문에 적당한 소수로 나머지 연산을 해줍시다. const int mod = 524287;
해시 충돌을 방지하기 위해 해시값을 두 개정도 생성하겠습니다.
해시 테이블을 만들어봅시다.
1 |
|
vector[첫 번째 해시값] = {두 번째 해시값, 구간 길이}
형태로 저장하겠습니다.
첫 번째 문자열에 있는 모든 구간에 대해 해시값을 구해줍시다.
x에는 첫 번째 해시값, y에는 두 번째 해시값이 들어갑니다.
1 |
|
두 번째 문자열에 있는 모든 구간에 대해 해시값을 구한 뒤, 해시 테이블에 있는지 판단해주면서 정답을 구합시다.
1 |
|
전체 코드
1 |
|