안녕하세요. BlockDMask 입니다.
오늘의 문제를 포스팅 해보겠습니다.
클라이밍 하고와서 손이 부들부들 떨리는데;;
24시가 되기전에 올려야하니, 샤워도 안하고 폭풍 포스팅을 해보겠습니다.소수를 구하는 문제인데;;
에라토스테네스의 체 (소수 구하는 방법) 방법을 이용하여 풀어야하는 문제입니다.
0. 제목
백준 1929 소수 구하기
BOJ 1929 소수 구하기
1. 문제설명
1 <= a <= b <= 1,000,000
a~b 까지 숫자의 범위를 집어 넣으면
그 숫자 사이에 있는 소수(prime number)들을 출력하는 문제입니다.
2. 풀이과정
일반적인 방법으로 소수를 구하면 "시간초과"가 나옵니다.
(자신보다 작은수로 % 했을때 나머지가 0인지)
에라토스테네스의 방법으로 풀어야 "맞았습니다" 가 나옵니다.
에라토스테네스의 방법을 간단히 과정을 보이겠습니다.
자세한 이론은 맨 밑에 URL 넣어두겠습니다.
1~20까지의 소수를 구한다고 했을때.
[1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15], [16], [17], [18], [19], [20]
1) 1은 소수가 아니니 버린다.
[1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15], [16], [17], [18], [19], [20]
2) [2]는 소수이다. -> 그러면 2의 배수는 소수가 아니다. -> 지운다.
[1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15], [16], [17], [18], [19], [20]
3) [3]는 소수이다. -> 그러면 3의 배수는 소수가 아니다. -> 지운다.
[1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15], [16], [17], [18], [19], [20]
3) [4]는 건너뛰고-> [5]소수이다. -> 그러면 5의 배수는 소수가 아니다. -> 지운다.(지워져있다.)
[1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15], [16], [17], [18], [19], [20]
3) [6]는 건너뛰고-> [7]소수이다. -> 그러면 7의 배수는 소수가 아니다. -> 지운다.(지워져있다.)
[1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15], [16], [17], [18], [19], [20]
[1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15], [16], [17], [18], [19], [20]
i 는 0 부터 증가.
이런방식으로 지우면 됩니다.
이번 문제에서는 숫자의 범위가 1,000,000 이므로
제곱을 했을때 1,000,000을 넘으면 break를 걸었습니다.
코드로 표현해보겠습니다.
3. 코드
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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #include<iostream> #include<cmath> #include<cstdio> using namespace std; // 1<= a <= b <= 1,000,000 int main(void){ int a,b; scanf("%d %d", &a, &b); //최대치 크기만큼 동적할당을 합니다 bool * arr = new bool[b+1]; //배열을 true로 초기화합니다 for(int i=0; i<b+1; i++){ arr[i] = true; } int j; //제곱의 수를 받을 변수 for(int i=2; i<b+1; i++){ if(arr[i]){ //true이면 if((unsigned int)pow(i, 2) > 1000001){ //제곱이 범위를 넘으면 for 문을 나옵니다 break; }else{ //이미 있는 소수들의 배수들을 지워줍니다. for( j = (int)pow(i, 2) ; j < b+1 ;){ arr[j] = false; //소수가 아닌 수들을 false로 바꿔줌 j = j+i; } } } } //1인경우를 제외해야하므로 a가 1이 들어왔을때, 2로 만들어줍니다 if(a == 1) a++; //true이면서, a보다 큰 값들을 출력! for(int i=a; i<b+1; i++){ if(arr[i] && i>= a) printf("%d\n", i); } delete []arr; // 동적할당 해제 return 0; } | cs |
4. 인증
문제 출처 : https://www.acmicpc.net/problem/1929
원리 출처 : http://terms.naver.com/entry.nhn?docId=1179083&cid=40942&categoryId=32204
감사합니다. 이번문제에서는 배운게 많습니다.
이렇게 소수를 구하는 방법이 있었다니 한 분야의 전문가들은 클라스가 다름을 느꼈습니다.
'<알고리즘 문제풀이&연습> > [C++] 백준, 프로그래머스 등등' 카테고리의 다른 글
[백준 2747] 피보나치 수 (2) | 2017.08.17 |
---|---|
[백준 2108] 통계학 (최빈값, 산술평균, 중앙값, 범위) (0) | 2017.08.11 |
[CodeGround] 하노이 타워(Hanoi Tower) (0) | 2017.08.07 |
[CodeGround] 극단적인 수 (0) | 2017.08.04 |
[백준 1181] 단어정렬 (vector, array) (1) | 2017.08.02 |
[백준 1475] 방 번호 (0) | 2017.08.01 |
[백준 10828] 스택 (C, C++ stack) (4) | 2017.08.01 |
[백준 11050] 이항계수 1 (반복, 재귀) (0) | 2017.07.31 |