컴퓨터공학/알고리듬 풀이
백준-약수, 배수와 소수 2단계 4134 다음 소수
cyphen156
2025. 6. 9. 09:50
주어진 수보다 크고 인접한 가장 작은 소수를 하나씩 출력한다.
매우 큰 범위의 소수가 도출될 수 있다.
-> 일반적인 방법론 사용 불가능
--> 확률론적 방법론 사용
// 밀러 - 라빈 소수 판정법 사용
제약사항
- 0 <= N <= 4*10**9 == 약 40억
주의 사항
꼭 한번 더 보고 이해해보기CPP풀이
다음 소수_4134.cpp
/**
* 백준 다음 소수_4134
* 주어진 수보다 크고 인접한 가장 작은 소수를 하나씩 출력한다.
*
* 매우 큰 범위의 소수가 도출될 수 있다.
* -> 일반적인 방법론 사용 불가능
* --> 확률론적 방법론 사용
* // 밀러 - 라빈 소수 판정법 사용
* 메모이제이션 사용
*
* 제한사항
*****************************************
* 0 <= N <= 4*10**9 == 약 40억 *
*****************************************
*
*
*
* 주의
* 꼭 다시 한번 더 보고 이해해보기
*
* 풀이시간 120분
*/
#include <iostream>
typedef unsigned long long ull;
using namespace std;
// 거듭제곱 연산을 통해 합성수인지 판단
ull ModuloPower(ull base, ull exponent, ull modulos);
// 밀러-라빈 소수 판정기
bool IsPrime(unsigned int n);
// 나보다 큰 최인접소수 찾기
unsigned int FindNextPrime(unsigned int input);
int main(void)
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int N;
cin >> N;
for (int i = 0; i < N; ++i)
{
unsigned int input;
cin >> input;
cout << FindNextPrime(input) << '\n';
}
return 0;
}
// 지수 연산
ull ModuloPower(ull base, ull exponent, ull modulos)
{
ull result = 1;
base %= modulos;
while(exponent > 0)
{
if (exponent & 1)
{
result = (result * base) % modulos;
}
exponent >>= 1;
base = (base * base) % modulos;
}
return result;
}
// 실제 소수 판정
bool IsPrime(unsigned int n)
{
// 예외 처리부
if (n < 2)
{
return false;
}
if (n == 2 || n == 3)
{
return true;
}
if (n % 2 == 0)
{
return false;
}
// n-1 = d * 2^r 꼴로 분해
unsigned int d = n - 1;
int r = 0;
while ((d & 1) == 0)
{
d >>= 1;
r++;
}
// 밑
unsigned int bases[3] = {2, 7, 61};
for (int a : bases)
{
// 예외처리
if (a >= n)
{
continue;
}
long long x = ModuloPower(a, d, n);
if (x == 1 || x == n - 1)
{
continue;
}
bool isPassed = false;
for (int i = 1; i < r; i++)
{
x = ModuloPower(x, 2, n);
if (x == n - 1)
{
isPassed = true;
break;
}
}
if (!isPassed)
{
return false;
}
}
return true;
}
unsigned int FindNextPrime(unsigned int input)
{
if (input <= 2)
{
return 2;
}
// 만약 Input이 짝수라면 항상 합성수가 나올 테니 1을 올려서 홀수로 만들어서 소수 판별 시작
if (input % 2 == 0)
{
++input;
}
// 단순하게 2씩 늘려가면서 순회
while (!IsPrime(input))
{
input += 2;
}
return input;
}
모든 예제 코드의 소스파일은 제 개인 깃허브 레포지토리에 있습니다.
Workspace/알고리듬 풀이 at main · cyphen156/Workspace
Studying . Contribute to cyphen156/Workspace development by creating an account on GitHub.
github.com