原题链接:蓝桥杯算法提高VIP-找素数
把int改成long long 就对了,太伤心了。。。
解题思路:一个合数n他的最小质因子不会超过sqrt(n),所以我们求区间[a,b]的素数,我们只需要
找出[2,sqrt(b)]以内的素数,然后将其倍数从[a,b]里面里面去掉就行,最后剩下的就是
[a,b]内的素数了。
注意:整形存不下,要用long long,区间不要开太大,也不要开太,还有,需要用到线性筛素数筛
选素数,普通方法会超时。
#include <iostream>
#include <stdio.h>
#include <string>
#include <cmath>
using namespace std;
typedef long long ll;
const int maxn = 1000001;
bool vis[maxn]; //标记数组,true是素数,false是合数
int ans[maxn]; //存储得到的素数
int tot;
bool isprime[maxn];
void Getprime(int n) //线性筛素数
{
vis[1] = true; //1不是素数
for (int i = 2; i <= n; i++) //进行判断
{
if (!vis[i])
ans[tot++] = i;
for (int j = 0; j < tot&&(ll)ans[j] * i <= n; j++)
/*用当前数i与i之前的素数相乘取得一个合数*/
{
vis[ans[j] * i] = true;
if (i%ans[j] == 0) break;
}
}
}
int main()
{
int n, m;
cin >> n >> m;
Getprime(sqrt(m)); //得到素数表
int num = m - n + 1;
for (int i = 0; i < tot; i++)
{
for (ll j = (ans[i] + n - 1) / ans[i];;j++)
/*(ans[i]+n-1)/ans[i]是求区间内的第一个数至少为i的几倍*/
{
if (j == 1)
continue;
if (ans[i] * j > m)
break;
isprime[ans[i] * j - n] = true; //true则不是素数
}
}
int cnt = 0;
for (int i = 0; i < num; i++)
{
if (!isprime[i]) cnt++; // 统计素数个数
}
cout << cnt << endl;
return 0;
}0.0分
4 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复