题目
4AM是绝地求生顶级的职业战队,他们打比赛总是采取慢进圈的策略。在最近的一次比赛中,当他们准备进圈的时候,发现圈里的许多位置都被其他战队所占据,他们被迫只能选择其他没被占领的位置。圈里的位置被标记为从1到n,4AM发现那些序号为合数的地方都被占领,此时你能帮助4AM找出他们还有几个地方可以去嘛。如n = 10时,序号为1,2,3,5,7的5个地方4AM都可以去(1 不是合数)。
输入格式:
一个正整数n(n <= 1000000)
输出格式:
一个整数(有几个地方4AM可以去)
输入样例1:
10
输出样例1:
5
输入样例2:
20
输出样例2:
9
#include <iostream>
#include <math.h>
using namespace std;
int num=0;
int a[100000];
bool judge(int n)
{
if(n==1 || n==2 || n==3 )
return true;
else if(n%2==0)
return false;
else
for(int i=2;a[i]<=sqrt(n);i++)
if(n%a[i]==0)
return false;
return true;
}
int main()
{
int n;
cin>>n;
int j=0;
for(int i=1;i<=n;i++)
{
if(judge(i))
{
a[j]=i;
j++;
num++;
}
}
cout<<num<<endl;
return 0;
}
分析
- 不是合数:质数,数字1也是不是合数
- 没错,题目的意思理解起来非常简单就是求出n以内的所有的素数,关键在于时间复杂度如何降低!
- 级别一:从i=2到n-1一个个进行取模
- 级别二:从i=2到sqrt(n)一个个进行取模
- 级别三:可以发现n是偶数一定是合数,所以先判断是否位偶数,再继续判断从3到sqrt(n)的所有奇数,i=2k+1(k=1,2,3,…),对n%i是否有等于0
- 级别四:其实上面的奇数中3是9的因子,判断过3就没必要判断9了,于是进一步可以有一个结论就是,如果模除小于n的质数为0则是合数,于是我们可以保存之前的质数用于下一次的判断。