6484

나는컴공생·2025년 3월 5일

SW검정준비

목록 보기
1/11

팩토리얼로 나타났을 때, 소인수분해하기

에라토스테네체의 체
1. 처음에 다 default true로 하기
2. i*i < n 인 i 까지 반복(sqrt(N))
3. %i == 0 이면 false로 바꾸기

현재 위치가 소수이면 primes vector 배열에 넣기
소수가 아닌 것들은 bool값 바꿔주기

10억 7은 int 안으로 들어올 수 있다.
그러나 곱하는 계산 과정 속에서 int 범위 넘을 수 있다.
long long으로 사용해줘야한다!

그릐고 n을 나는 임시 변수로 저장하지 않아서 값이 바뀌었다.
그래서 제대로 된 답이 나오지 않았다.
변수를 그대로 사용할 때 뒤에서 다시 사용하면, 해당 값을 임시변수에 저장하여 사용하는 습관을 기르자.

#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <vector>

#define div (1000000007)
#define MAXN 100000
using namespace std;
bool isprime[MAXN + 1];
vector<int> primes;
int main(int argc, char** argv)
{
	int test_case;
	int T;
	freopen("input.txt", "r", stdin);
	cin >> T;
	//소수 전처리
	for (int i = 0; i <= MAXN; ++i) isprime[i] = 1; //모두 true로 초기화
	isprime[1] = false; isprime[0] = false;
	for (int i = 2; i * i <= MAXN; i++) {
		if (!isprime[i]) continue; //소수가 아니면 pass
		for (int j = i * i; j <= 100000; j += i) {
			isprime[j] = false;
		}
	}
	for (int i = 2; i <= MAXN; ++i) {
		if (isprime[i]) {
			primes.push_back(i);
		}
	}
	for (test_case = 1; test_case <= T; ++test_case)
	{
		int n, k;
		long long ans = 1;
		cin >> n >> k;
		//TODO: nCk 의 약수의 개수를 구하여라.
		//1. 소인수분해
		unordered_map <int, int> um; // 소수, 지수
		for (int prime : primes) {
			if (prime > n) break;
			int factor_cnt = 0;
            //n!
			int temp_n = n;
			while (temp_n) {
				temp_n /= prime;
				factor_cnt += temp_n;
			}
			//k!
			int temp_k = k;
			while (temp_k) {
				temp_k /= prime;
				factor_cnt -= temp_k;
			}
            //(n-k)!
			int temp_nk = n - k;
			while (temp_nk) {
				temp_nk /= prime;
				factor_cnt -= temp_nk;
			}

			if (factor_cnt > 0) {
				long long tmp = (factor_cnt + 1) % div;
				ans = (ans * tmp) % div;
			}
		}

		cout << "#" << test_case << " " << ans << "\n";
	}
	return 0;//정상종료시 반드시 0을 리턴해야합니다.
}

0개의 댓글