일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 문자열
- 정렬
- C
- 이분탐색
- 큐
- 해시를사용한집합과맵
- C언어
- 논문리뷰
- SQL
- 수학
- 프로그래머스
- 사칙연산
- MySQL
- 백준알고리즘
- 그리디알고리즘
- 다이나믹프로그래밍
- 프로그래머스sql
- 소수판정
- 논문구현
- C++
- 구현
- 정수론
- 백준
- 그리디
- 이진탐색
- 프로그래머스연습문제
- 브루트포스알고리즘
- 자료구조
- Image Classification
- 프로그래머스코딩테스트
- Today
- Total
초보 개발자의 이야기, 릿허브
[C++] 백준 2581번 소수 본문
1. 문제이해
https://www.acmicpc.net/problem/2581
M 이상 N 이하의 자연수 중 소수인 것을 찾아
해당 값들의 합과 값들 중 최솟값을 출력하는 것이 목표이다.
2. 문제풀이
M 이상 N 이하의 소수를 모두 찾아 해당 값들의 합과 최솟값을 출력하는 문제이다.
이전에도 비슷한 문제를 풀이한 적이 있어서, 해당 방법과 비슷한 방법으로 풀이했다.
제곱근 값(루트값)을 기준으로, 앞의 있는 수들과 뒤에 있는 수들은 서로 짝을 이루므로,
제곱근 값을 기준으로 앞에 있는 수들로 나눠진다면, 뒤에 있는 수들 또한 나눠지게 된다.
이렇듯 제곱근 값(루트값)을 기준으로 앞에 있는 수들만 검사해,
for문을 통해 검사해야 하는 범위를 절반으로 줄여 시간초과를 해결하는 방식을 이용했다.
위 방법을 이용해 범위 내의 소수를 모두 구한 뒤 벡터값에 집어넣고,
값들을 모두 더하고, 첫번째 값(가장 작은 값)을 출력하는 식으로 코드를 작성했다.
자세한 풀이방식은 아래 포스팅을 참고하자.
https://beginnerdeveloper-lit.tistory.com/65
3. 소스코드
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main() {
vector <int> v;
int M, N;
int not_prime_num;
int root; // 제곱근
int sum = 0;
cin >> M >> N;
for (int i = M; i <= N; i++) {
not_prime_num = 0;
root = (int)sqrt(i);
// 1은 소수가 아니므로 따로 count
if (i == 1) {
not_prime_num++;
continue;
}
// 2부터 제곱근값 전까지 나눠지는 수가 있다면 소수가 아님
for (int j = 2; j <= root; j++) {
if (i % j == 0) {
not_prime_num++;
break;
}
}
// 약수의 개수가 0개 = 소수이므로 벡터에 저장
if (not_prime_num == 0) {
v.push_back(i);
}
}
// 만약 범위 내에 소수가 없다면, -1 출력
if (v.empty()) {
cout << "-1";
}
else {
for (int i = 0; i < v.size(); i++) {
sum += v[i];
}
cout << sum << "\n" << v[0];
}
return 0;
}
이전 포스팅과 풀이방식은 동일하다.
제곱근 값을 이용해 해당 범위 내의 소수들을 모두 구해 벡터에 저장해주었다.
만약 소수인 것이 없다면, -1 을 출력하고,
아니라면 벡터값에 저장된 소수들의 합과 최솟값(v[0])을 출력하도록 했다.
주석이 없는 코드는 왼쪽 아래 더보기를 참고 바랍니다.😊
<주석 없는 코드>
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main() {
vector <int> v;
int M, N;
int not_prime_num;
int root;
int sum = 0;
cin >> M >> N;
for (int i = M; i <= N; i++) {
not_prime_num = 0;
root = (int)sqrt(i);
if (i == 1) {
not_prime_num++;
continue;
}
for (int j = 2; j <= root; j++) {
if (i % j == 0) {
not_prime_num++;
break;
}
}
if (not_prime_num == 0) {
v.push_back(i);
}
}
if (v.empty()) {
cout << "-1";
}
else {
for (int i = 0; i < v.size(); i++) {
sum += v[i];
}
cout << sum << "\n" << v[0];
}
return 0;
}
이전 문제에 대해 확실한 풀이방법을 알고 있어서 쉽게 풀이 가능한 문제였다.
전에거를 안 풀어봤다면 어려웠을 것 같다..😥
문제에 대한 질문이나 지적은 언제나 감사히 받고 있습니다.😊
'코딩테스트 > 📗 백준 (BOJ)' 카테고리의 다른 글
[C++] 백준 11561번 좌표 정렬하기 2 (0) | 2022.02.03 |
---|---|
[C++] 백준 1912번 연속합 (0) | 2022.02.01 |
[C++] 백준 15903번 카드 합체 놀이 (0) | 2022.01.29 |
[C++] 백준 10819번 차이를 최대로 (0) | 2022.01.25 |
[C++] 백준 15729번 방탈출 (0) | 2022.01.22 |