https://www.acmicpc.net/problem/1124
[필자 사고]
에스테라토스의 채를 이용하여 푸는 문제다.
다만 해당 채를 구한다음 언더프라임 수를 구할 때 무작정 모든 경우의 수를 생각해서 나누면 문제가 생긴다.
```
for (int i = 2; i <= MAX; i++) {
int n = i;
for (int k = 2; k <= sqrt(n); k++) {
while (n % k == 0) {
resultCount[i]++;
n /= k;
}
}
if (n > 1) resultCount[i]++;
}
```
여기서 안쪽 for문에서 정해진 n을 나눌수 있는 수들을 정할때 sqrt(n)을 통해 반복문 횟수를 줄여줘야지
시간 초과를 면할 수 있다.
sqrt()할수 있는 이유는 자연수를 소인수 분해하는 수들은 반드시 sqrt()를 넘지 않는다는 법칙 때문이다.
100을 예로보자면
100의 소인수 숫자들은 반드시 10보다 작거나 같다.
100 = 2*5*2*5
아래는 자세한 코드해설이다.
[코드 해설]
Input() 함수
- 사용자로부터 두 정수 A, B를 입력받는다.
- isPrime이라는 불리언 배열을 초기화하여 0부터 MAX까지의 범위에서 소수를 미리 판별한다.
- 에라토스테네스의 체 알고리즘을 사용해 isPrime[i]가 true일 때, 그 배수들을 모두 false로 바꿔 소수가 아님을 표시한다.
- 이를 통해 특정 수가 소수인지 빠르게 판단할 수 있는 사전 정보가 준비된다.
Game_Start() 함수
- resultCount 배열을 초기화하여 각 수가 갖는 **소인수의 총 개수(중복 포함)**를 저장한다.
- 예를 들어 12는 2x2x3 이므로 개수는 3이다.
- 각 정수 i에 대해 다음을 수행한다.
- n = i라고 두고, 2부터 sqrt(n)까지의 수로 나누어떨어질 때마다 소인수 개수를 세고 n을 나눈다.
- 이 과정을 반복하면 중복된 소인수도 포함해 정확히 몇 번 나눠졌는지 알 수 있다.
- 소인수 분해가 끝난 후 n이 1보다 크면, 이는 마지막에 남은 소수이므로 개수를 1 더한다.
- A부터 B까지의 모든 수를 탐색하며, 해당 수의 소인수 개수가 소수인지 확인한다.
- 이때 resultCount[i]가 소수이면 언더프라임으로 간주하여 result를 증가시킨다.
- 최종적으로 언더프라임의 개수를 출력한다.
main() 함수
- 위의 두 함수인 Input()과 Game_Start()를 순차적으로 호출하여 프로그램을 실행시킨다.
- 입력 → 소수 및 소인수 분석 → 언더프라임 개수 출력 흐름을 담당한다.
[소스 코드]
#include <iostream>
#include <vector>
#include <cmath>
#define MAX 100000
using namespace std;
int A, B;
vector<bool> isPrime;
vector<int> resultCount;
void Input() {
cin >> A >> B;
isPrime.resize(MAX + 1, true);
isPrime[0] = false;
isPrime[1] = false;
for (int i = 2; i<=sqrt(MAX); i++) {
if (!isPrime[i]) continue;
for (int k = i * i; k <= MAX; k += i) {
isPrime[k] = false;
}
}
}
void Game_Start() {
resultCount.resize(MAX + 1, 0);
for (int i = 2; i <= MAX; i++) {
int n = i;
for (int k = 2; k <= sqrt(n); k++) {
while (n % k == 0) {
resultCount[i]++;
n /= k;
}
}
if (n > 1) resultCount[i]++;
}
int result = 0;
for (int i = A; i <= B; i++) {
if (isPrime[resultCount[i]]) result++;
}
cout << result;
}
int main(void) {
Input();
Game_Start();
return 0;
}
'백준 > 수학' 카테고리의 다른 글
백준 1011 c++ "Fly me to the Alpha Centauri" (0) | 2025.06.02 |
---|---|
백준 6588 c++ "골드바흐의 추측" -PlusUltraCode- (0) | 2025.05.29 |
백준 9020 c++ "골드바흐의 추측" -PlusUltraCode- (0) | 2025.05.26 |
백준 4948 c++ "베르트랑 공준" -PlusUltraCode- (0) | 2025.05.25 |
백준 10517 c++ "Radar Coverage" -PlusUltraCode- (0) | 2025.01.20 |