-
JUNGOL 실력키우기 수학2 - 소수와 합성수 | 소수 | 소수 구하기 | 소수의 개수보관함 2020. 2. 5. 23:33
기초 다지기에서 배운 내용을 응용하여 문제를 해결해야 하는 실력 키우기입니다.
실력 키우기는 비슷한 문제 유형별로 묶어서 풀어보겠습니다.
이번 포스팅에서는 수학2의 소수 시리즈를 풀어보겠습니다.
2811 : 소수와 합성수
이 문제는 단순하게 2부터 입력된 숫자까지를 돌면서 나눠지는 값이 있는지를 확인하여 나눠지는 경우 소수로 판단할 수도 있으나 조금 더 생각하면 범위를 줄일 수 있다는 것을 알 수 있습니다.
숫자를 나눌 수 있는 가장 큰 값은 해당 숫자의 루트 값 까지라는 것입니다.
즉, 2부터 해당 숫자까지를 나누는 게 아니라 해당 숫자의 루트까지만 나눠서 확인하면 되는 것입니다.
그렇게 하면 최대로 나누는 횟수는 10억 회가 아니라 10억의 루트 값인 31,622 회가 됩니다.
#include <iostream> #include <cmath> using namespace std; bool IsPrime(int num); int main(void) { int num; for (int i = 0; i < 5; ++i) { cin >> num; if (num == 1) { cout << "number one" << endl; } else if (IsPrime(num)) { cout << "prime number" << endl; } else { cout << "composite number" << endl; } } } bool IsPrime(int num) { if (num < 2) return false; size_t limit{ static_cast<size_t>(sqrt(num)) }; for (int i = 2; i <= limit; ++i) { if (num % i == 0) return false; } return true; }
http://www.jungol.co.kr/bbs/board.php?bo_table=pbank&wr_id=452&sca=2040
JUNGOL | 소수와 합성수 > 문제은행
소수(prime number)란 1보다 큰 자연수 중 1과 자기 자신 두 개만을 약수로 갖는 수를 말한다. 합성수(composite number)란 1보다 큰 자연수 중 소수가 아닌 수를 말하며 3개 이상의 약수를 갖는다. 1은 소수도 합성수도 아니다. 5개의 자연수를 입력받아 소수인지 합성수인지를 판단하는 프로그램을 작성하시오. 10억 이하의 자연수 5개가 공백으로 구분되어 주어진다.
www.jungol.co.kr
1740 : 소수
이 문제도 이전에 만든 소수를 확인하는 함수를 사용해 소수인 경우 sum에 값을 누적하고 최초로 소수로 판정된 경우 최소 값으로 저장해 출력하면 됩니다.
마찬가지로 소수의 최솟값이 존재하지 않는다면 소수가 없는 것으로 판단해 -1을 출력하면 됩니다.
#include <iostream> #include <cmath> using namespace std; bool IsPrime(int num); int main(void) { int m, n; cin >> m >> n; int sum{ 0 }, minPrime{ 10001 }; for (int i = m; i <= n; ++i) { if (IsPrime(i)) { sum += i; if (minPrime > 10000) { minPrime = i; } } } if (minPrime > 10000) { cout << -1 << endl; } else { cout << sum << endl; cout << minPrime << endl; } } bool IsPrime(int num) { if (num < 2) return false; size_t limit{ static_cast<size_t>(sqrt(num)) }; for (int i = 2; i <= limit; ++i) { if (num % i == 0) return false; } return true; }
http://www.jungol.co.kr/bbs/board.php?bo_table=pbank&wr_id=1013&sca=2040
JUNGOL | 소수 > 문제은행
자연수 M과 N이 주어질 때 M이상 N이하의 자연수 중 소수인 것을 모두 골라 이들 소수의 합과 최소값을 찾는 프로그램을 작성하시오. 예를 들어 M=60, N=100이 경우 60이상 100이하의 자연수 중 소수는 61, 67, 71, 73, 79, 83, 89, 97 총 8개가 있으므로, 이들 소수의 합은 620이고, 최소값은 61이 된다. 입력의 첫째 줄에 M이, 둘째 줄에 N이 주어진다. M과 N은 10,000이하의 자연수이며, M은 N보다 같거나
www.jungol.co.kr
1901 : 소수 구하기
이번 문제는 최대 값 까지의 소수를 구하고 주어진 값과 가장 가까운 소수를 찾아 출력하면 되는 문제입니다.
모든 소수를 구하는 방법은 에라토스테네스의 체라는 방법을 사용하면 되는데, 이것에 대해 간략하게 설명하자면 어떤 값이 소수일 때 그 값보다 크고 해당 값으로 나눠지는 수는 모두 합성 수라는 것을 알고 있으므로 미리 체크를 위한 배열을 만들어 소수를 찾았을 때 그 소수 이후에 해당 소수 값 간격의 모든 수를 합성 수로 체크하여 소수를 구하는 방법입니다.
#include <iostream> #include <vector> using namespace std; void CalculatePrime(); bool checker[1000001]{}; vector<int> primeList; int main(void) { CalculatePrime(); int n; cin >> n; int num; for (int i = 0; i < n; ++i) { cin >> num; int bigIndex{ 0 }; for (int j = 0; j < primeList.size(); ++j) { if (primeList[j] > num) { bigIndex = j; break; } } int diffToBig{ primeList[bigIndex] - num }; int diffToSmall{ (bigIndex > 0) ? num - primeList[bigIndex - 1] : diffToBig + 1 }; int leastDiff{ (diffToBig < diffToSmall) ? diffToBig : diffToSmall }; if (diffToSmall == leastDiff) { cout << primeList[bigIndex - 1] << ' '; } if (diffToBig == leastDiff) { cout << primeList[bigIndex] << ' '; } cout << endl; } } void CalculatePrime() { for (int i = 2; i <= 1000000; ++i) { if (checker[i] == false) { primeList.push_back(i); for (int j = i * 2; j <= 1000000; j += i) { checker[j] = true; } } } }
http://www.jungol.co.kr/bbs/board.php?bo_table=pbank&wr_id=1174&sca=2040
JUNGOL | 소수 구하기 > 문제은행
첫 번째 줄에는 처리해야 할 수의 개수 N을 입력 받는다. (N은 100이하의 정수) 다음 줄에는 처리해야할 수 N개(M1부터 Mn까지)를 한 줄에 한 개씩 차례로 입력 받는다. (Mi 는 1,000,000 이하의 양의 정수) 데이터의 크기가 주어진 범위를 벗어나는 입력은 없다. 임의의 값 Mi에 대해 차이가 가장 작은 소수를 구하여 출력한다. 만약 차이가 같은 소수가 여러 개이면 작은수부터 모두 출력한다. 출력되는 값은 1이상 1,000,000이하의 소
www.jungol.co.kr
2813 : 소수의 개수
이 문제는 이전에 설명한 에라토스테네스의 체를 구할 때 나오는 체크용 배열로 쉽게 풀 수 있습니다.
체크가 된 값이 합성수이므로 체크가 되지 않은 경우 카운트를 세면 됩니다.
#include <iostream> using namespace std; void CalculatePrime(); bool checker[2000001]{}; int main(void) { CalculatePrime(); int n, m; cin >> n >> m; int primeCount{ 0 }; for (int i = n; i <= m; ++i) { if (!checker[i]) { primeCount++; } } cout << primeCount << endl; } void CalculatePrime() { checker[1] = true; for (int i = 2; i <= 2000000; ++i) { if (checker[i] == false) { for (int j = i * 2; j <= 2000000; j += i) { checker[j] = true; } } } }
http://www.jungol.co.kr/bbs/board.php?bo_table=pbank&wr_id=2079&sca=2040
JUNGOL | 소수의 개수 > 문제은행
소수(prime number)란 1보다 큰 자연수 중 1과 자기 자신 두 개만을 약수로 갖는 수를 말한다. 자연수 M과 N을 입력받아 M부터 N까지 소수의 개수를 구하여 출력하는 프로그램을 작성하시오. 자연수 M과 N이 공백으로 구분되어 주어진다. (1 ≤ M ≤ N ≤ 2,000,000)
www.jungol.co.kr