※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 3896번 문제인 소수 사이 수열이다.
문제는 아래 링크를 확인하자.

https://www.acmicpc.net/problem/3896 

 

3896번: 소수 사이 수열

첫째 줄에 테스트 케이스의 개수 T가 주어진다. 테스트 케이스는 한 줄로 이루어져 있고, 한 줄에 정수 k가 주어진다. 각각의 정수는 1보다 크고, 100000번째 소수(1299709)와 작거나 같다.

www.acmicpc.net

에라토스테네스의 체를 이용하여 10만개의 소수를 먼저 구해주자.

 

소수 사이 수열이 존재하지 않는 숫자들은 1과(1보다 작은 소수가 없기 때문) 소수들 뿐이라는 것을 관찰하자.

따라서 이 문제를 해결하려면 1 또는 소수가 입력으로 들어오면 0을 출력해주고 그렇지 않은 경우 주어진 수보다 큰 소수와 작은 소수의 차를 출력해주면 된다.

 

주어진 수보다 큰 소수와 작은 소수는 이분탐색(binary search)를 통해 빠르게 구할 수 있다.

 

아래는 제출한 소스코드이다.

#include <iostream>
#include <vector>
using namespace std;

vector<bool> sieve(1299710);
int prime[100000];

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	int idx = 0;
	sieve[0] = 1;
	for (int i = 2; i < 1140; i++) {
		if (sieve[i]) continue;
		for (int j = i * i; j < 1299710; j += i) sieve[j] = 1;
	}

	for (int i = 2; i < 1299710; i++) {
		if (sieve[i]) continue;
		prime[idx++] = i;
	}

	int T; cin >> T;
	while (T--) {
		int x; cin >> x;
		if (!sieve[x]) cout << 0 << '\n';
		else {
			int l, r;
			
			int L = 0, R = 99999;
			while (L < R) {
				int mid = (L + R) / 2;
				if (x < prime[mid]) R = mid;
				else L = mid + 1;
			}
			r = R;

			L = 0, R = 99999;
			while (L < R) {
				int mid = (L + R) / 2 + 1;
				if (prime[mid] < x) L = mid;
				else R = mid - 1;
			}
			l = L;

			cout << prime[r] - prime[l] << '\n';
		}
	}
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 3020 // C++] 개똥벌레  (0) 2021.11.05
[BOJ 2512 // C++] 예산  (0) 2021.11.04
[BOJ 1477 // C++] 휴게소 세우기  (0) 2021.11.02
[BOJ 2110 // C++] 공유기 설치  (0) 2021.11.01
[BOJ 2819 // C++] 상근이의 로봇  (0) 2021.10.31

+ Recent posts