boj488. 小妹妹个数-素数个数题(打表...)
我爱死这道颠覆世界观的题目了...
时间限制 3000 ms
内存限制 65536 KB
题目描述
喜欢焦叔叔的小妹妹实在是太多了,以至于焦叔叔不得不给她们编号1-N。焦叔叔对于编号为质数的小妹妹有种特别的好感,由于有好感的小妹妹数目太多,焦叔叔自己都数不清楚了,请你来帮忙数一下。
输入格式
多组数据,每行一个正整数N,N不大于1000000000。
数据组数小于15。
输出格式
每行一个数字,有好感的小妹妹数。
输入样例
5
输出样例
3
10^9开根号后大概是31622把10^9分(1 - 31622)(31622*1+1 - 31622*2)(31622*2+1 - 31622*3)...(31622*31622+1 - 31622*31623)份,然后手动打表输出每一份范围的数包含的素数个数(个数是累加的,不是分段的):
eg: 123456=(31622*2+1 - 31622*3)的素数个数+ i中的素数个数(123456>= i >=31622*3+1)
前面查表,后面手动暴力算就好了。神奇吧,我吓坏了。
当然,对于这个求解,如何快速算出某个范围内的个数也是很有考究的,用了某个神的代码,我觉得不错,我大概用了45s算出来了,思路就是一般的素数筛选法,去掉2的倍数,余下的第一个一定是下一个素数,再去掉它的倍数。。。
下面是我打表计算范围的代码
#include
#define max 1000000000///bool可以开到这么大,确实很惊奇,最让我惊奇的是c++才能开到这么大,c好像不可以。。。
#define deta 31622
bool flag[max];
int main()
{
freopen("su.txt","w+",stdout);
int n,m;
__int64 i,j,num=0;
for(i=2;i<=max;i++)
{
if(!flag[i])
{
for(j=i*i;j<=max;j=j+i)
flag[j]=true;
}
}
n=1;m=31622;
for(i=2;i<=max;i++)
{
if(!flag[i])
{
//printf("%I64d ",i);//这句如过不注释的话,可以输出每一个质数具体是多少
num++;
}
if(i==m)
{
printf("%I64d,",num);
n=m+1;
m+=deta;
}
}
return 0;
}