일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 브루트포스
- 알고리즘
- hackerrank
- dynamic programming
- 소수
- 시뮬레이션
- 그리디
- 동적 계획법
- 구현
- Algorithm
- koitp
- 잠실
- PS
- SWEA
- 완전탐색
- 에라토스테네스의 체
- 백트래킹
- dfs
- 해커랭크
- BOJ
- 백준
- 다이나믹 프로그래밍
- DP
- BFS
- 스택
- 맛집
- 삼성 SDS 대학생 알고리즘 특강
- sw expert academy
- 삼성 기출
- C++
- Today
- Total
펭로그
[C++] 백준 BOJ 2960 에라토스테네스의 체 본문
시작 숫자부터 해당 숫자만큼의 배수로 탐색하여 답을 찾아가면 된다.
단 한번도 특정 숫자로 나누어 떨어지지 않은 숫자는 모두 소수이고 그 소수의 배수들은 소수가 아닌 수가 된다.
소수를 구하는 알고리즘은 다음과 같다.
처음으로 지워지는 숫자인 파란색은 소수이고 지워진 수는 소수의 N 배수이다.
배수가 되는 순간 소수가 아니기 때문에 당연히 파란색만 소수가 된다.
<초기 값>
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
<1회 실행> 2의 배수 제거
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
<2회 실행> 3의 배수 제거
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
<3회 실행> 5의 배수 제거 (4의 배수는 이미 제거 됨)
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
<4회 실행> 7의 배수 제거 (5의 배수는 이미 제거 됨)
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
<5회 실행> 11의 배수 제거 (8,9,10의 배수는 이미 제거 됨)
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
<6회 실행> 13의 배수 제거 (12의 배수는 이미 제거 됨)
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
<7회 실행> 17의 배수 제거 (14,15,16의 배수는 이미 제거 됨)
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
<8회 실행> 19의 배수 제거 (18의 배수는 이미 제거 됨)
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
배수를 지워나가면서 놀랍게도 파란색으로 칠해진 숫자(처음으로 지워진 숫자)는 모두 소수임을 알 수 있다.
에라토스테네스의 체는 이런 식으로 소수를 구하는 알고리즘이다.
해당 순서가 지워졌을 경우를 0으로 하였고 지워진 것으로 판단되면 continue 하여 루프를 계속한다.
입력에 해당하는 값이 나왔을 때 루프를 탈출한다.
따로 소수를 구하는 문제가 아니기 때문에 소수를 별도로 저장하진 않았다.
이 문제의 경우 소수를 직접 구하는 문제가 아니라 약간 아쉬운 감이 있다.
코드 하단에 소수 배열을 구하는 부분을 따로 정리해두었다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | // BOJ 2960 에라토스테네스의 체 #include <bits/stdc++.h> using namespace std; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); freopen("../input.txt", "r", stdin); int num, k; cin >> num >> k; int pnum = 2; vector<int> arr(num + 1, 0); for (int i = 2; i <= num; i++) arr[i] = i; int cnt = 0; int result; while (true) { for (int i = pnum; i <= num; i += pnum) { if (arr[i] == 0) continue; result = arr[i]; arr[i] = 0; if (++cnt == k) goto END; } pnum++; } END: cout << result; return 0; } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 | vector <bool> isPrime(maxNum + 1, false); vector <int> pnum; for (int i = 2; i <= maxNum; i++) isPrime[i] = true; for (int i = 2; i <= maxNum; i++) { if (isPrime[i]) { pnum.push_back(i); for (int j = i * 2; j <= maxNum; j += i) isPrime[j] = false; } } | cs |
'Study > PS(Algorithm)' 카테고리의 다른 글
1753 (0) | 2018.08.01 |
---|---|
[C++] 백준 BOJ 1260 DFS와 BFS (0) | 2018.07.31 |
[C++] 백준 BOJ 2252 줄 세우기 (0) | 2018.07.31 |
[C++] 백준 BOJ 1717 집합의 표현 (시간초과 해결) (0) | 2018.07.31 |
[C++] 백준 BOJ 1966 프린터 큐 (0) | 2018.07.31 |