思想
题目的意思就是让你输出第n+1个素数。那么我们就可以通过筛法找出第n+1个素数即可。
刚开始这样写只通过了80%:
#include<iostream>
#define int long long
using namespace std;
int ans;
signed main()
{
cin.tie(nullptr)->sync_with_stdio(false);
int n; cin >> n;
for (int i = 2;; i++)
{
int flag = 1;
for (int j = 2; j * j <= i; j++)
{
if (i % j == 0)
{
flag = 0;
}
}
if (flag)
{
ans++;
}
if (ans > n)
{
cout << i << endl;
break;
}
}
return 0;
}
这是因为在第二层循环里没有进行Break。比如4%2==0,那么4就不是素数了,就没必要再枚举下去4%3了,直接Break,减少时间复杂度。
埃氏筛法
#include <iostream>
#include <vector>
#include<cstring>
using namespace std;
vector<int> primes;
const int N=2000000;
bool book[N];
void isPrime(int x)
{
memset(book,true,sizeof book);
book[0] = book[1] = false;
for (int i = 2; i * i <= x; ++i) {
if (book[i]) { //如果没被筛掉
for (int j = 2 ;j <= x/i; j ++) {
book[i*j] = false; //筛掉合数
}
}
}
}
void solve() {
int n;cin>>n;
isPrime(2000000);
for (int i = 2; i <= 2000000; ++i) {
if (book[i]) {
primes.push_back(i);
}
}
cout<< primes[n]; //下标从0开始,输出第n个数实际上就是输出第n+1个数
}
int main() {
solve();
return 0;
}
注意这里将N定义为1e5+10会发生越界,因为1e5+10只能访问100010,有可能会访问到19999,所以我们需要把N定义为2000000,避免越界。