1. 程式人生 > >藍橋杯 歷屆試題 幸運數(暴力打表)

藍橋杯 歷屆試題 幸運數(暴力打表)

第一個 pac for ans include inpu putchar desc 幸運數

Description

幸運數是波蘭數學家烏拉姆命名的。它采用與生成素數類似的“篩法”生成


首先從1開始寫出自然數1,2,3,4,5,6,....

1 就是第一個幸運數。

我們從2這個數開始。把所有序號能被2整除的項刪除,變為:

1 _ 3 _ 5 _ 7 _ 9 ....

把它們縮緊,重新記序,為:

1 3 5 7 9 .... 。這時,3為第2個幸運數,然後把所有能被3整除的序號位置的數刪去。註意,是序號位置,不是那個數本身能否被3整除!! 刪除的應該是5,11, 17, ...

此時7為第3個幸運數,然後再刪去序號位置能被7整除的(19,39,...)

最後剩下的序列類似:

1, 3, 7, 9, 13, 15, 21, 25, 31, 33, 37, 43, 49, 51, 63, 67, 69, 73, 75, 79, ...

Input

輸入兩個正整數m n, 用空格分開 (m < n < 1000*1000)

Output

程序輸出 位於m和n之間的幸運數的個數(不包含m和n)。

Sample Input

樣例輸入1
1 20

樣例輸入2
30 69

Sample Output

樣例輸出1
5

樣例輸出2
8

Source

藍橋杯 a[i]=i代表i在序列中
a[i]=0代表i不在序列中
vis[i]=1代表i是幸運數
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define INF 99999999
#define me(a,x) memset(a,x,sizeof(a))
int mon1[13]= {0,31,28,31,30,31,30,31,31,30,31,30,31};
int mon2[13]= {0,31,29,31,30,31,30,31,31,30,31,30,31};
int dir[4][2]= {{0,1},{0,-1},{1,0},{-1,0}};
int fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};//i的階乘 LL getval() { LL ret(0); char c; while((c=getchar())== ||c==\n||c==\r); ret=c-0; while((c=getchar())!= &&c!=\n&&c!=\r) ret=ret*10+c-0; return ret; } void out(int a) { if(a>9) out(a/10); putchar(a%10+0); } int kt(int a[],int n)//康托展開 { int ans=0; for(int i=1; i<=n; i++) //下標從1開始 { int c=0; for(int j=i+1; j<=n; j++) { if(a[j]<a[i]) c++; } ans+=(c*fac[n-i]); } return ans+1; } #define max_v 1000005 int a[max_v]; int vis[max_v]; void f(int k,int n)//消去序號%k==0的數 { int c=0; for(int i=1;i<=n;i++) { if(a[i]==0) continue; c++; if(c%k==0) { a[i]=0; } } } int ff(int k,int n)//輸出序列中第k個數是多少 { int c=0; for(int i=1;i<=n;i++) { if(a[i]!=0) c++; if(c==k) { return a[i]; } } return -1; } int main() { int m,n; scanf("%d %d",&m,&n); me(vis,0); for(int i=1;i<=n;i++) a[i]=i; int k=2; int v=2; while(v<=n) { f(v,n); v=ff(k,n); if(v==-1) break; vis[v]=1; k++; } int c=0; for(int i=m+1;i<=n-1;i++) { if(vis[i]) c++; } printf("%d\n",c); return 0; } /* a[i]=i代表i在序列中 a[i]=0代表i不在序列中 */

藍橋杯 歷屆試題 幸運數(暴力打表)