欧拉计划简介,本系列希望以通俗易懂的语言、简洁的代码,带大家体会数学与编程结合的魅力。
Problem 7:100011000110001st primeBy
标签:质数、质数筛法
原文:By listing the first six prime numbers: 222, 333, 555, 777, 111111, and 131313, we can see that the 666th prime is 131313. What is the 10 00110\ 00110 001st prime number?
翻译:前666个质数分别是222、333、555、777、111111和131313。第10 00110\ 00110 001个质数是多少?
题解:质数判定解法时间复杂度 O(nn)O(n\sqrt{n})O(nn),埃式筛法解法时间复杂度 O(nloglogn)O(nloglogn)O(nloglogn),欧拉筛 O(n)O(n)O(n)。
下面展示一下三种解法的代码。
质数判定 代码:
#include <bits/stdc++.h>
using namespace std;
bool check(int x) {
if (x <= 1) return 0;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) return 0;
}
return 1;
}
int main() {
int cnt = 0, i = 1;
while (1) {
if (check(i)) {
cnt++;
if (cnt == 10001) {
cout << i << endl;
return 0;
}
}
i++;
}
return 0;
}
埃式筛法 代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
bool isPrime[N]; // 0是 1不是质数
int main() {
isPrime[0] = isPrime[1] = 1;
for (int i = 2; i < N; i++) {
if (!isPrime[i]) {
for (int j = 2 * i; j < N; j += i) {
isPrime[j] = 1;
}
}
}
int cnt = 0;
for (int i = 2; i < N; i++) {
if (!isPrime[i]) {
cnt++;
if (cnt == 10001) {
cout << i << endl;
return 0;
}
}
}
return 0;
}
欧拉筛法 代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int prime[N];
bool isPrime[N]; // 0是 1不是质数
int main() {
isPrime[0] = isPrime[1] = 1;
int cnt = 1;
for (int i = 2; i <= N; i++) {
if (!isPrime[i]) prime[cnt++] = i;
for (int j = 1; j < cnt && i * prime[j] <= N; j++) {
// 将以prime[j]]为最小质因数的合数筛掉
isPrime[i * prime[j]] = 1;
// 保证只筛到以prime[j]为最小质因数的数
if (i % prime[j] == 0) break;
}
}
cout << prime[10001];
return 0;
}
“Project Euler exists to encourage, challenge, and develop the skills and enjoyment of anyone with an interest in the fascinating world of mathematics.”
“欧拉计划的存在,是为了每个对数学感兴趣的人,鼓励他们,挑战他们,并最终培养他们的能力与乐趣。”