牛客网编程马拉松--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 ", ans ); } return 0; }