题解 UVA11105 【H-半素数 Semi-prime H-numbers】

做这道题之前首先要掌握的是线性筛的模板

附上题目链接

https://www.luogu.org/problem/P3383

首先这道题目的范围有些特殊必须是% 4 == 1的数才行

所以可以这样

直接把线性筛的模板拿过来将里面的每个数挨个枚举,每一次的++i 或者++j可以改为 += 4

这样每一次枚举的就都是“H数 ”了

然后不考虑“H数 ”之外的数,用这里面的数进行素数筛选 将H-素数都筛出来

在最后的时候两重循环枚举素数将他们的乘积标注出来最后 剩下的H数就都会是H-合数了

完整代码

#include<iostream>
#include<cstdio>
#include<cmath>

using namespace std;
const int Max = 1000005;
const int M = 1000001;
int ans[Max];
bool use[Max];
bool vis[Max];
int prime[Max];
int a[Max];
int js = 0;
int main()
{
    int tot = 0;
    for(int i = 5;i <= M;i += 4)
    {
        if(use[i] == true)continue; 
        prime[++ tot] = i;
        for(int j = 1;j * i <= M;j += 4)//线性筛模板晒出H-素数 
            use[i * j] = true;
    }
    for(int i = 1;i <= tot;i ++)
    {
        for(int j = 1;j <= tot;j ++)//双重循环枚举 
        {
            if(prime[i] * prime[j] > M)break;//大于最大的范围break掉这一层循环 
            vis[prime[i] * prime[j]] = 1;//标记出来 
        }
    }
    for(int i = 1;i <= M;++ i)
    {
        ans[i] += ans[i - 1];//先继承前面H-合数的个数 
        if(vis[i] == true)//如果当前的数也是H-合数 
        ans[i] ++;//计数器累加 
    }
    int n;
    while(scanf("%d",&n))
    {
        if(n == 0)break;
        else
        cout<<n<<" "<<ans[n]<<endl;
    }
    return 0;
}

 

上一篇:GEM/SECS设备自动化和EAP自动化软件


下一篇:mysql集群架构半同步复制和并行复制