• poj3292


    题意:对于4*n+1(n为自然数)组成的集合,乘法在该集合中是封闭的。现规定h-prime是这个集合的数字中只有1和本身能整除的数(不含1)。其余为h合数。从h合数中划分出一部分数字,这些数是由两个h素数相乘得到的,称之为h-semi。现要求在指定1~n范围内有多少个h-semi。

    分析:筛法,就是把h合数全筛掉,开始默认所有的都是h素数,然后枚举两个数,把他们的乘积筛掉。这道题要求h-semi,所以我们要改进一下,把原来的true false标注变为0(h素数), 1(非h-semi的合数), 2(h-semi)的标注。在筛的过程中如果发现枚举的两个数暂时没被筛掉,我们就把他们的乘积标注为h-semi(前提是它没被标为1)。容易论证,任何一个非h-semi的合数在此过程中都会至少被标为1一次(设a<=b<=c,为三个组成非h-semi,d的因子。枚举到a,c时,a*c被标为2。然后会枚举到b和a×c。则必然将a*b*c标为1),所以即使我们之前误标为2,后来也会被更正为1。

    View Code
    #include <iostream>
    #include
    <cstdlib>
    #include
    <cstring>
    #include
    <cstdio>
    usingnamespace std;

    #define maxn 250005

    int n, prime[maxn], ncount[maxn];

    int main()
    {
    //freopen("D:\\t.txt", "r", stdin);
    memset(prime, 0, sizeof(prime));
    int temp;
    n
    = maxn *4;
    for (int i =1; (i *4+1) * (i *4+1) <= n; i++)
    {
    for (int j = i; (temp = (i *4+1) * (j *4+1)) <= n; j++)
    {
    if (prime[i] ==0&& prime[j] ==0&& prime[(temp -1) /4] !=1)
    prime[((i
    *4+1) * (j *4+1) -1) /4] =2;
    else
    prime[((i
    *4+1) * (j *4+1) -1) /4] =1;
    }
    }
    ncount[
    0] =0;
    for (int i =1; i < maxn; i++)
    if (prime[i] ==2)
    ncount[i]
    = ncount[i -1] +1;
    else
    ncount[i]
    = ncount[i -1];
    while (scanf("%d", &n) != EOF && n !=0)
    {
    printf(
    "%d %d\n", n, ncount[(n -1) /4]);
    }
    return0;
    }
  • 相关阅读:
    谷歌浏览器设置跨域失败
    Validation of viewstate MAC failed 解决办法--zt
    如何查看Oracle客户端版本及位数(Windows系统)(转)
    程序员集锦
    如何最快速地适应新的工作
    Oracle 03113
    Shell中字符串、数值的比较
    K8S客户端安装及使用
    kubectl的使用
    Helm 入门指南
  • 原文地址:https://www.cnblogs.com/rainydays/p/1966180.html
Copyright © 2020-2023  润新知