자료구조&알고리즘/알고리즘 - 대회 알고리즘

[알고리즘 문제 풀이][조합] 백준 17205번 - 진우의 비밀번호

초코쨔응 2022. 1. 19. 00:10

백준 17205번 진우의 비밀번호 문제입니다.

(조합론)

 

- 문제 설명: https://www.acmicpc.net/problem/17205

- 문제 풀이:

 

가능한 비밀번호가 최대 3자리라면 a, aa, aaa, aab, aac, ..., azy, azz, b, ba 이런 식으로 나타나게 됩니다.

그러면 매 자리마다 가능한 경우의 수를 합해주면 됩니다.

 

a

b

...

z

===> 여기가 총 26개

a a

a b

a c

a ...

a z

====> 여기는 a~z * a~z 를 생각하면 총 26 * 26개

a a a

a a b

a a c

a a ...

a a z

======> 여기는 a~z * a~z * a~z 를 생각하면 총 26 * 26 * 26개가 됩니다.

 

그렇다면 만일 최대 길이가 3이고, 문제에서 주어진 첫 번째 자리가 b 라면, b 전까지의 경우의 수는 a 로 시작하는 모든 3가지 경우일 것입니다. a / a a ~ a z / a a a ~ a z z 까지가 모두 해당할 것입니다.

 

따라서 a 인 1개 + 26 * 26 개 + 26 * 26 * 26 개를 우선 더해주어야 합니다.

 

그 다음에는 다음 자리에 가서 똑같이 고려를 해주어야 합니다. 만일 두 번째 자리가 c 라면 (그래서 비밀번호가 bc 라면), 맨 앞 자리는 b 로 고정하고 두 번째 자리부터 고려했을 때 가능한 경우는 a ~ b / a a ~a z 와 b a ~ b z 가 해당될 것입니다. 그러면 a, b 로 2개 + 26 * 26개 * (a, b 2개) 로 구할 수 있습니다.

 

이를 일반화하면, 각 자리마다 이전 알파벳까지 가능한 등비 수열의 합 (26 + 26 * 26 + 26 * 26 * 26 ...) 과 이전 알파벳의 개수를 합해주면 됩니다. 예를 들어, 위의 bc 예시에서, 첫번째 자리는 1개 + 1개 * (26 부터 시작하는 등비수열의 합) 입니다. 두번째 자리는 2개 + 2개 * (26 부터 시작하는 등비수열의 합) 이 됩니다.

 

(텍스트로 적어서 복잡해보이지만, 가능한 경우를 세로로 쭉 써보다보면 규칙성을 조금 더 쉽게 파악할 수 있습니다.)

 

- 코드

N = int(input())
pwd = input()
ans = 0
anum = ord('a')
N -= 1
for alpha in pwd:
    diff = ord(alpha) - anum
    if diff > 0:
        ans += (diff)*26*(26**N-1)//(25) + diff
    ans += 1
    N -= 1
print(ans)

 

- 실수 포인트 & 반례:

1. 본 문제는 별다른 반례가 없습니다. 1자리의 경우가 잘 커버 되는지 확인하기 위해 아래 예시를 넣어보면 좋습니다.

입력)
1
a

정답)
1

입력)
1
c

정답)
3