Redraiment猜想
运行时限: 1000 ms 单次运行时限: 1000 ms 内存限制: 64 MB
总提交: 2345次 通过: 505次
总提交: 2345次 通过: 505次
redraiment在家极度无聊,于是找了张纸开始统计素数的个数。
设函数f(n)返回从1->n之间素数的个数。
redraiment发现:
f(1) = 0
f(10) = 4
f(100) = 25
...
满足g(m) = 17 * m 2 / 3 - 22 * m / 3 + 5 / 3
其中m为n的位数。
他很激动,是不是自己发现了素数分布的规律了!
请你设计一个程序,求出1->n范围内素数的个数,来验证redraiment是不是正确的,也许还可以得诺贝尔奖呢。^_^
设函数f(n)返回从1->n之间素数的个数。
redraiment发现:
f(1) = 0
f(10) = 4
f(100) = 25
...
满足g(m) = 17 * m 2 / 3 - 22 * m / 3 + 5 / 3
其中m为n的位数。
他很激动,是不是自己发现了素数分布的规律了!
请你设计一个程序,求出1->n范围内素数的个数,来验证redraiment是不是正确的,也许还可以得诺贝尔奖呢。^_^
输入包括多组数据。
每组数据仅有一个整数n (1≤n≤10,000,000)。
输入以0结束
每组数据仅有一个整数n (1≤n≤10,000,000)。
输入以0结束
对于每组数据输入,输出一行,为1->n(包括n)之间的素数的个数
可见格式 | 带空格和换行符的格式 | 带空格和换行符的格式说明 |
1 10 65 100 0
Original | Transformed | 带空格和换行符的格式说明 |
0 4 18 25
个人理解:用改进版埃氏筛法和动态规划
时间可以很短
AC情况:
代码C:
# include <stdio.h>
# include <math.h>
# define N 10000001
char A[N];
int B[N];
int main(){
int i,j,Q=sqrt(N)+1,k=0;
for(A[0]=A[1]=1,i=2;i<Q;i++)
if(!A[i])
{
for(j=i<<1;j<N;j+=i)
A[j]=1;
B[i]=B[i-1]+1;
}
else B[i]=B[i-1];
do{
B[i]=B[i-1]+(!A[i]);
}while(i++<N);
while(scanf("%d",&i)&&i){
printf("%d\n",B[i]);
}
return 0;
}
短小精悍 ^!^
另一道差不多
素数求和
运行时限: 10000 ms 单次运行时限: 10000 ms 内存限制: 32 MB
总提交: 6次 通过: 1次
总提交: 6次 通过: 1次
输入一个自然数n,求小于等于n的素数之和.
可见格式 | 带空格和换行符的格式 | 带空格和换行符的格式说明 |
2
Original | Transformed | 带空格和换行符的格式说明 |
2
数据规模和约定
测试样例保证 2 <= n <= 2,000,000
测试样例保证 2 <= n <= 2,000,000
算法提高
# include <stdio.h>
# include <math.h>
# define N 2000005
char A[N];
long long B[N];
int main(){
int i,j,Q=sqrt(N)+1,k=0;
for(A[0]=A[1]=1,i=2;i<Q;i++)
if(!A[i])
{
for(B[i]=B[i-1]+i,j=i<<1;j<N;j+=i)
A[j]=1;
}
else B[i]=B[i-1];
do{
if(!A[i])B[i]=B[i-1]+i;
else B[i]=B[i-1];
}while(i++<N);
while(scanf("%d",&i)!=EOF){
printf("%lld\n",B[i]);
}
return 0;
}