• 问题 D: 【数论】Semi-prime H-numbers


    译文描述
    这个问题是基于戴维·希尔伯特(David Hilbert)的一项练习得出的,戴维·希尔伯特(David Hilbert)在教学法上建议对4n + 1数的理论进行研究。在这里,我们只做一点。

    H数是一个正数,是四的整数倍:1、5、9、13、17、21,…是H数。对于这个问题,我们假装这些是唯一的数字。H数在乘法下是闭合的。

    与常规整数一样,我们将H数划分为单位,H素数和H组合。1是唯一的单位。如果H数h不是单位,则为H素数,并且仅以一种方式为两个H数的乘积:1×h。其余数字是H组合的。

    例如,前几个H复合材料为:5×5 = 25、5×9 = 45、5×13 = 65、9×9 = 81、5×17 = 85。

    您的任务是计算H半素数。H半素数是一个H数,正好是两个H素数的乘积。两个H-素数可以相等或不同。在上面的示例中,所有五个数字均为H-半质数。125 = 5×5×5不是H-半素数,因为它是三个H-素数的乘积。

    输入
    输入的每一行包含一个H数≤1,000,001。输入的最后一行包含0,并且不应处理此行。

    输出
    对于每个输入的H数h,以示例中显示的格式打印一行h,并在1和h之间(含1和h)打印H半素数。

    这个题目就相当于让先筛选H-素数, 找0到h中有多少个数是两个h-素数乘到一起的,然后这个时候我们就改进一下筛选素数的方法, 如果i是一个H-素数,那么和i属于同一类的一定是i * (4x + 1) , 也就是将i乘上(4x + 1) , 题目规定(4x + 1)是h数, 所以i * (4x + 1)一定是H数 但一定不是H-素数,以为现在他有两个因子i和4i + 1 , 我们就这样构造一下,将线性筛选素数改改,然后就出来了,

    #include <iostream>
    using namespace std;
    const int N = 1e6 + 10 ;
    int vis[N] , prime[N] ; 
    int cnt[N] ;
    int st[N] ;
    int tot ;
    void get()
    {
    	for(int i = 5 ;i < N ;i += 4) 
    	 {
    	 	if(!vis[i]) 
    	 	prime[++ tot] = i ;
    	 	for(int j = i ;j < N ;j += 4 * i)
    	 	 vis[j] = true ;
    	 }
    	 for(int i = 1 ;i <= tot ;i ++)
    	  for(int j =  1 ;j <= i && prime[i] * prime[j] < N ;j ++)
    	   st[prime[i] * prime[j]] = 1 ;
    	for(int i = 1 ;i < N ;i ++)
    	 cnt[i] = cnt[i - 1] + st[i] ; 
    }
    int main()
    {
    	get() ;
    	int a , b ;
    	while(cin >> a && a != 0)
    	 cout << a << " " << cnt[a] << endl ;
    	return 0;
    }
    
    每次做题提醒自己:题目到底有没有读懂,有没有分析彻底、算法够不够贪心、暴力够不够优雅。
  • 相关阅读:
    cocos2d-x 纹理研究
    cocos2d-x 获取图片的某像素点的RGBA颜色
    cocos2d-x Menu、MenuItem
    cocos2d-x ScrollView、TableView
    cocos2d-x RenderTexture
    cocos2d-x NotificationCenter
    cocos2d-x ClippingNode
    cocos2d-x Animation
    JDK,JRE,JVM区别与联系(ZZ)
    SQL中join的用法
  • 原文地址:https://www.cnblogs.com/spnooyseed/p/12870895.html
Copyright © 2020-2023  润新知