牛客网编程马拉松--Nowcoder猜想
题目描述
nowcoder在家极度无聊,于是找了张纸开始统计素数的个数。
设函数f(n)返回从1-n之间素数的个数。
nowcoder 发现:
f(1) = 0
f(10) = 4
f(100) = 25
...
满足g(m) = 17 * m^2 / 3 - 22 * m / 3 + 5 / 3
其中m为n的位数。
他很激动,是不是自己发现了素数分布的规律了!
请你设计一个程序,求出f(n),来验证nowcoder是不是正确的,也许还可以得诺贝尔奖呢。^_^
设函数f(n)返回从1-n之间素数的个数。
nowcoder 发现:
f(1) = 0
f(10) = 4
f(100) = 25
...
满足g(m) = 17 * m^2 / 3 - 22 * m / 3 + 5 / 3
其中m为n的位数。
他很激动,是不是自己发现了素数分布的规律了!
请你设计一个程序,求出f(n),来验证nowcoder是不是正确的,也许还可以得诺贝尔奖呢。^_^
输入描述:
输入包括多组数据。
每组数据仅有一个整数n (1≤n≤10000000)。
输出描述:
对于每组数据输入,输出一行,为1->n(包括n)之间的素数的个数。
示例1
输入
1
10
65
100
0
输出
0
4
18
25
// write your code here cpp
#include <cstdio>
#include <cstdlib>
#include <cstring>
const int MAXN = 10000000 + 10000;
const int MAXM = 1000000;
char vis[MAXN];
int cnt, prime[MAXM];
void init(){
memset(vis, 0, sizeof(vis));
cnt = 0;
for(int i=2; i<MAXN; ++i){
if(vis[i] == 0){
prime[cnt++] = i;
for(int j=2*i; j<MAXN; j+=i){
vis[j] = 1;
}
}
}
}
int Find(int v){
int mid, l = 0, r = cnt - 1;
while(l <= r){
mid = l + (r - l)/2;
if( prime[mid] > v && prime[mid-1] <= v ){
return mid;
}else if(prime[mid] > v){
r = mid - 1;
}else{
l = mid + 1;
}
}
return -1;
}
int main(){
init();
int n, ans;
while(scanf("%d", &n) != EOF){
if(n == 0){
break;
}
if(n <= 1){
ans = 0;
}else{
ans = Find(n);
}
printf("%d\n", ans );
}
return 0;
}