ìƒ�ê°� ¶
n! 를 구성하는 2 <= k <= n � k� �수를 구하는 방법과,
kê°€ 소수ì�¸ì§€ 아닌지 íŒ�별하는 방법ì—� ë”°ë�¼ ì†�ë�„ê°€ ê²°ì •ë�œë‹¤.
kê°€ 소수ì�¸ì§€ 아닌지 íŒ�별하는 방법ì—� ë”°ë�¼ ì†�ë�„ê°€ ê²°ì •ë�œë‹¤.
기본ì �으로 në§Œí�¼ í�¬ê¸°ì�˜ ë°°ì—´ facì�„ ìž¡ê³ í•´ë‹¹ ì�¸ë�±ìФì�˜ ì�¸ìˆ˜ì�˜ 개수를 넣는다. (ex.fac8 ì�´ë©´ 8ì—� 해당하는 ì�¸ìˆ˜ì�˜ 개수 즉 3ì�´ 들어간다.)
ì�´ë ‡ê²Œ ë°°ì—´ì�„ ìž¡ì�€ ì�´ìœ 는 예를들어 나중ì—� 16ì�˜ ì�¸ìˆ˜ì�˜ 개수를 구한다면 16 = 8x2 ì�´ë¯€ë¡œ fac16 = fac8+1 = 4ê°€ ë�œë‹¤.
fac8ì�€ 미리 êµ¬í•´ì ¸ ë°°ì—´ì—� ì €ìž¥ë�˜ì–´ìžˆë�˜ ê°’ ì�´ë¯€ë¡œ 계산ì�´ 바로 나온다.
ì�´ë ‡ê²Œ ë°°ì—´ì�„ ìž¡ì�€ ì�´ìœ 는 예를들어 나중ì—� 16ì�˜ ì�¸ìˆ˜ì�˜ 개수를 구한다면 16 = 8x2 ì�´ë¯€ë¡œ fac16 = fac8+1 = 4ê°€ ë�œë‹¤.
fac8ì�€ 미리 êµ¬í•´ì ¸ ë°°ì—´ì—� ì €ìž¥ë�˜ì–´ìžˆë�˜ ê°’ ì�´ë¯€ë¡œ 계산ì�´ 바로 나온다.
하지만 k가 소수�면 �러한 방법� 통하지 않는다. 소수는 나름� �별�칙� 따� �단. 소수�별�는 수학공�� �용�는� �것� �략 

소스 ¶
~cpp
import java.util.*;
import java.math.*;
public class FactorialFactors2 {
final int CASE_N = 1000000; //í…ŒìŠ¤íŠ¸í• ì¼€ì�´ìФ 수
int fac[] = new int[CASE_N+1]; //ì�¸ìˆ˜ì €ìž¥ë°°ì—´
ArrayList<Integer> prime = new ArrayList<Integer>();
boolean isPrime(int num){
for(int k=0;k<prime.size();k++){
if(num%prime.get(k)==0)
return false;
}
return true;
}
void printResult(){
int total=0;
for(int i=2;i<=CASE_N; i++)
total+=fac[i];
System.out.println(total);
}
void run(){
long time = System.currentTimeMillis();
prime.add(2);
fac[2] = 1;
int sqrt = (int)Math.sqrt(CASE_N);
//n!ì�´ë¯€ë¡œ ì•Œê³ ë¦¬ì¦˜ìƒ� 2는 ì‚¬ì „ì—� 미리 ì²˜ë¦¬í•˜ê³ 3~n까지 ê°�ê°�ì�˜ 수ì—� 대하여 ì�¸ìˆ˜ë¥¼ 계산한다.
for(int i=3;i<=CASE_N;i++){
int num = i;
//num� �수� 개수를 구하는 루프.
for(int j=2; num!=1;){
if(num%j == 0){
num = num/j;
fac[i]++;
fac[i]+=fac[num];
break;
}
else
j++;
//7로 나눌때까지 ì•ˆë‚˜ëˆ ë–¨ì–´ì§€ëŠ” 수 ì�´ë©´ 소수를 ì�˜ì‹¬í•´ë³¸ë‹¤.
if (j == 7 && isPrime(num) == true) {
fac[i]++;
if (num <= sqrt) // 우리가 필요로하는 소수는 sqrt보다 작� 소수만 있� �다.
prime.add(num);
break;
}
}
}
printResult();
System.out.print(System.currentTimeMillis()-time);
}
public static void main(String[] args) {
new FactorialFactors2().run();
}
}










