영어 단어의 첫글자와 끝글자가 서로 같고 그 사이의 글자가 순서가 뒤섞인채로 구성이 같으면 같은 단어로 취급한다
abcde는 acbde, abdce,... 등과 같다
단어 사전과 문장들이 주어질때 각 문장을 해석하는 방법의 수를 구한다
-------------------------------------------------------------------------------------------------------------------------------------------
영어 단어가 bakers, brakes, breaks,...등이 주어질때
먼저 bakers를 보면 bakers, bkaers, bekras, berkas, bearks,... 등이 서로 같은 단어들이다.
만약에 어떤 문장의 단어 A가 주어질때 bakers와 같은지 다른지를 비교할려면 어떻게 해야할까?
A의 첫글자와 끝글자를 찾은 다음 이것이 b,s인지를 비교한다
그리고 그 사이의 글자들이 a,k,e,r로 구성되어있는지를 비교하면 된다
이때 정렬해놓으면 순열들은 하나의 고유한 값을 가지게 된다
즉, bakers는 [b,s]에 대하여 a,k,e,r을 정렬하여 [a,e,k,r]로 해놓으면
예를 들어 bkaers가 들어올때 먼저 [b,s]로 찾고, k,a,e,r을 정렬하여 [a,e,k,r]이 되므로 서로 같다고 알 수 있게 된다
단어의 길이가 100자를 넘지 않기 때문에 10^4 * 10^2*log10^2으로 10^7정도로 시간도 괜찮다
from sys import stdin
n = int(stdin.readline())
d = {}
for _ in range(n):
s = stdin.readline().rstrip()
if len(s) == 1:
d[s[0]] = d.get(s[0],0) + 1
else:
if d.get((s[0],s[-1]),0) == 0:
d[(s[0],s[-1])] = {}
S = list(s[1:-1])
S.sort()
S = ''.join(S)
d[(s[0],s[-1])][S] = d[(s[0],s[-1])].get(S,0) + 1
길이가 1인 경우에는 첫글자만 모아두면 될거고
이제 이렇게 모아두면 문장을 읽어서 단어 하나씩 끊은 다음 각 단어에 대해서
첫글자, 끝글자를 가져와 사전에서 hash한 다음 첫글자와 끝글자 사이를 정렬해서 그것을 키로 가지는 value가
몇개인지 알면 각 개수를 곱하면 될 것이다
예를 들어 문장이 A B C로 이루어져있다면 각 단어는 [A,B,C] 3개로 있고
A가 몇가지로 해석될 수 있는지 첫글자와 끝글자 A[0], A[-1]을 hash하여 찾고
A[1:-1]을 정렬하여 그것이 몇가지 있는지 찾아본다
B,C 도 마찬가지
그러면 곱의 법칙에 따라 A*B*C가 [A,B,C]가 해석될 수 있는 방법의 수일 것
m = int(stdin.readline())
for _ in range(m):
s = list(stdin.readline().rstrip().split())
count = 1
for c in s:
if len(c) == 1:
count *= d.get(c[0],0)
else:
C = list(c[1:-1])
C.sort()
C = ''.join(C)
count *= d.get((c[0],c[-1]),{}).get(C,0)
print(count)
'알고리즘 > 애드 혹 알고리즘' 카테고리의 다른 글
구간 내 가장 큰 해밍거리를 가지는 두 정수를 구하는 방법 (0) | 2025.04.08 |
---|---|
야바위에서 바로 왼쪽이나 오른쪽으로 한번만 이동시킬 수 있을때 가능한 위치 구하기 (0) | 2025.03.26 |
m개의 원소를 조건에 맞게 n개의 원소에 배치하는 방법 (0) | 2024.12.02 |
주어진 점들 중 최대 맨해튼 거리(Manhattan Distance)를 빠르게 찾는 방법 (0) | 2024.10.23 |
논리식의 일부를 바꿔서 원하는 결과가 나오게 만드는 방법 (0) | 2024.09.23 |