文章目录
- 蓝桥杯
- 2.质数
- 7.质数
- 质数数目
- 纯质数
蓝桥杯
2.质数
求质数的几种方法:
#include<iostream>
#include<algorithm>
using namespace std;
bool is_primer1(int n)
{
if (n < 2) return n;
//for (int i = 2; i < n; i++)
for (int i = 2; i <= n / i; i++)//对循环进行优化
{
if (n % i == 0) return false;
}
return true;
}
int primes[1000], cnt = 0;
bool st[1000];
void is_primer2(int n)
{
for (int i = 2; i <= n; i++)
{
if (!st[i])
{
primes[cnt++] = i;
cout << i << " ";
for (int j = i + i; j <= n; j += i)
{
st[j] = true;
}
}
}
}
int main()
{
int n = 1000;
//打印1000内的所有质数
//1.试除法
for (int i = 2; i <= n; i++)
{
if (is_primer1(i)) cout << i << " ";
}
cout << endl;
//2.埃氏筛法
is_primer2(n);
return 0;
}
2.质数
使用上面两种的任意一种求质数的方式就可以求出第2019个 质数是什么。
#include <iostream>
#include <cmath>
using namespace std;
int is_prime(int n)
{
for(int i=2;i<=sqrt(n);i++)
{
if(n%i==0)
return 0;
}
return 1;
}
int main()
{
int count=1;
for(int i=2;i<20000;i++)
{
if(count==2019&&is_prime(i))
cout<<i;
if(is_prime(i))
{
count++;
}
}
return 0;
}
#include <iostream>
using namespace std;
const int N=100005;
int primes[N];
int cnt=0;
bool st[N];
int main()
{
int n=100000;
for(int i=2;i<=n;i++)
{
if(!st[i])
{
primes[cnt++]=i;
for(int j=i+i;j<=n;j+=i)
{
st[j]=true;
}
}
}
cout<<primes[2018]<<endl;
return 0;
}
7.质数
因为数据量不是很大,所以我们直接从1到N对数进行判断或者,将所有1000前的质数提前计算好并且储存在primes中,输出到我们需要的1到N之间的质数集合也是可以的。这里注意题目中的不包含N,做好边界判断即可。
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
bool is_prime(int n)
{
if(n<2) return 0;
for(int i=2;i<=sqrt(n);i++)
{
if(n%i==0) return 0;
}
return 1;
}
int main()
{
int cnt=0,n;
cin>>n;
for(int i=1;i<n;i++)
{
if(is_prime(i))
{
cnt++;
cout<<i<<' ';
}
}
if(n!=1) cout<<endl;
cout<<cnt;
return 0;
}
#include <iostream>
using namespace std;
typedef long long ll;
const int N = 10010;
ll primes[N], cnt = 0;
bool st[N];
int main()
{
int n = 0, count = 0;
cin >> n;
for (int i = 2; i <= N; i++)
{
if (!st[i])
{
primes[cnt++] = i;
for (int j = i + i; j <= N; j += i)
st[j] = true;
}
}
for (int i = 0; i < 10000; i++)
{
if (primes[i] < n && primes[i] != 0)
{
cout << primes[i] << " ";
count++;
}
}
cout << endl;
cout << count << endl;
return 0;
}
质数数目
直接累加从1到N的数中所有的质数个数。
#include <iostream>
#include<cmath>
using namespace std;
int prime(int n)
{
if(n==0||n==1)
return 0;
for(int i=2;i<=sqrt(n);i++)
{
if(n%i==0)
return 0;
}
return 1;
}
int main()
{
int n;cin>>n;
int count=0;
for(int i=0;i<=n;i++)
{
if(prime(i))
count++;
}
cout<<count;
return 0;
}
纯质数
在没有涉及到比较大的数时,我们其实直接使用sqrt优化遍历质数即可。在纯质数中我们在判断是否是质数的前提下,在对数进行一次判断是否个个数位上全是质数。两者的条件都符合进行累加,最后的结果就是我们所需要的。
函数判断顺序的优化
这里有一个要注意的小点:
if (is_pure(i)&&is_prime(i))
if (is_prime(i)&&is_pure(i))
上面的两行代码看上去作用似乎是完全一样的,确实没错,两者的代码含义都是一致的——即满足 is_pure(i) 又 满足 is_prime(i) 条件。但是两者的代码运行的时间效率相差很大,前一个函数的判断数位上是否全是质数,最多进行8次循环就可以返回结果;后一个函数的作用是判断质数时间复杂度接近O(n),相当于要把这个数从1到自身完全遍历一遍。两函数的计算效率相差极大。
我们把效率高的函数 is_pure(i) 放在前面,编译器会先执行条件运算符中靠左的一方,如果不满足就直接跳过该数,不会对其进行判断质数的操作,效率大大提升。
类似的还有对闰年二月的修改,判断二月的条件比较判断闰年的条件简单,放在左侧,若不满足是否为2月这个条件,也就没必要判断是否为闰年:
if(month==2&&is_leap_year(year)) month[2]=29;
#include<cmath>
#include <iostream>
using namespace std;
int is_prime(int n)
{
for (int i = 2; i <= sqrt(n); i++)
{
if (n % i == 0) return 0;
}
return 1;
}
int is_pure(int n)
{
while (n)
{
int t = n % 10;
if (t == 0 || t == 1 || t == 4 || t == 6 || t == 8 || t == 9)
return 0;
n /= 10;
}
return 1;
}
int main()
{
int count = 0;
for (int i = 1; i <= 20210605; i++)
{
if (is_pure(i)&&is_prime(i))
{
count++;
}
}
cout << count << endl;
return 0;
}