티스토리 뷰

문제 링크

https://algospot.com/judge/problem/read/PASS486

 

algospot.com :: PASS486

비밀번호 486 문제 정보 문제 재훈이는 한 번 담배를 끊겠다고 다짐할 때마다 이메일 계정 비밀번호를 바꾸는 습관이 있습니다. 재훈이는 비밀번호를 항상 "no-smok**X**" 와 같이 정하는데, 여기서 X는 1자리 이상의 자연수입니다. 재훈이에게는 k번째로 금연을 다짐할 때는 항상 정확히 k개의 약수를 갖는 숫자로 X를 선택하는 습관이 있습니다. 예를 들어 재훈이가 12번째로 금연을 다짐했을 때 쓴 비밀번호는 no-smok486 이었습니다. 486 에

algospot.com

 

약수 n개를 가지고있는 숫자를 범위 low부터 high까지의 숫자들 중에서 찾아내는 문제입니다.

정수 x의 약수의 개수는 x 이전의 모든 값에 대한 약수의 개수와 가장 작은 소인수 값을 알고있으면 찾을 수 있습니다.

 

 

예를 들어 12의 약수의 개수를 알고싶고 1부터 11까지의 약수의 개수와 12를 포함한 모든 값들의 가장 작은 소인수를 알고 있습니다.

그럼 12를 12의 가장 작은 소인수인 2로 나누면 6이 됩니다.

12를 n, 6을 p라고 하고

 

n과 p의 가장 작은 소인수는 2로 같습니다.

이렇게 n과 p의 가장 작은 소인수가 같은 경우 p의 가장 작은 소인수의 개수를 확인합니다.

p의 가장 작은 소인수의 개수 2는 1개 입니다.

그럼 n은 p에서 공통으로 가장 작은 소인수인 2를 한번 더 곱한 값이기 때문에 n에서의 가장 작은 소인수인 2의 개수는 2개라고 할 수 있습니다.

이 값을 a라고 했을 때 

다음과 같은 식으로 n의 약수의 개수를 구할 수 있습니다.

 

만약 n과 p의 가장 작은 소인수가 서로 다른 경우

예를 들어 6은 6의 가장 작은 소인수가 2인데 6을 2로 나눈 3의 가장 작은 소인수는 3으로 서로 다릅니다.

그러면 6의 소인수에는 2가 1개밖에 존재하지 않기 때문에 factors[3]에 2를 곱해주면 6의 약수의 개수를 구할 수 있습니다. 그러므로 a를 1로 두면 위의 식과 동일하게 적용할 수 있습니다.

 

이렇게 소인수의 개수를 먼저 구하는 방식으로 문제를 해결하기 위해서는 에라토스테네스의 체 알고리즘을 사용하여 1부터 주어진 최대값인 1천만 까지 각 수의 가장 작은 소인수를 먼저 구해주면 됩니다.

 

 

구현 코드