蓝桥杯 历届试题 幸运数(暴力打表)

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不在序列中
*/
复制代码

 

posted @   西*风  阅读(425)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示