POj  3292 Semi-prime H-numbers

这篇博客探讨了基于希尔伯特练习的H数理论,重点介绍了H数的乘法封闭性、分类(单位、H素数、H合数),并详细解释了如何计算给定范围内的H半素数数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Semi-prime H-numbers
Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 5400Accepted: 2209

Description

This problem is based on an exercise of David Hilbert, who pedagogically suggested that one study the theory of 4n+1 numbers. Here, we do only a bit of that.

An H-number is a positive number which is one more than a multiple of four: 1, 5, 9, 13, 17, 21,... are the H-numbers. For this problem we pretend that these are the only numbers. The H-numbers are closed under multiplication.

As with regular integers, we partition the H-numbers into units, H-primes, and H-composites. 1 is the only unit. An H-number h is H-prime if it is not the unit, and is the product of two H-numbers in only one way: 1 × h. The rest of the numbers are H-composite.

For examples, the first few H-composites are: 5 × 5 = 25, 5 × 9 = 45, 5 × 13 = 65, 9 × 9 = 81, 5 × 17 = 85.

Your task is to count the number of H-semi-primes. An H-semi-prime is an H-number which is the product of exactly two H-primes. The two H-primes may be equal or different. In the example above, all five numbers are H-semi-primes. 125 = 5 × 5 × 5 is not an H-semi-prime, because it's the product of three H-primes.

Input

Each line of input contains an H-number ≤ 1,000,001. The last line of input contains 0 and this line should not be processed.

Output

For each inputted H-number h, print a line stating h and the number of H-semi-primes between 1 and h inclusive, separated by one space in the format shown in the sample.

Sample Input

21 
85
789
0

Sample Output

21 0
85 5
789 62

Source


唉,崩溃啊,差点儿超内存,32ms, 9352K,
打表,记下所有“素数”,然后再打表记下个数,最后输出。
代码和测试数据如下:
#include<stdio.h>
int prm[1100008],hnum[1100008],a[1100008]={0},qun[1100008]={0};
__int64 q;
int main()
{
int m,n,i=0,j,k,num;
for(j=1;j<=1000001;j+=4)
{
hnum[i++]=j;
a[j]=1;
}m=i;k=0;
for(i=1;i<m;i++)
if(a[hnum[i]]==1)
{
prm[k++]=hnum[i];
for(j=i;j<m;j++)
{
q=hnum[i]*hnum[j];
if(q>1000001||(hnum[i]>1001&&hnum[j]>1001))break;
a[hnum[i]*hnum[j]]=2;
}
}
num=0;m=0;
for(i=0;i<k;i++)
for(j=i;j<k;j++)
{
q=hnum[i]*hnum[j];
if(q>1000001||(hnum[i]>1001&&hnum[j]>1001))break;
if(prm[i]*prm[j]<=1000001)
{
qun[prm[i]*prm[j]]=1;
a[m++]=prm[i]*prm[j];
}
}
for(i=1;i<=1000001;i++)qun[i]+=qun[i-1];
while(scanf("%d",&n),n)
{
printf("%d %d\n",n,qun[n]);
}
return 0;
}
这是学长的代码,超简单,唉,学长就是学长啊!
#include<stdio.h>
#include<string.h>
#define N 1000002
int flag[N],a[N];
int main()
{
int i,j,n;
memset(flag,-1,sizeof(flag));
memset(a,0,sizeof(a));
for(i=5;i<1001;i+=4){
for(j=i;i*j<N;j+=4)
flag[i*j]=0;
}
for(i=5;i<1001;i+=4)
for(j=i;i*j<N&&flag[i];j+=4)
if(flag[j])
a[i*j]=1;
for(i=1;i<N;i++)a[i]+=a[i-1];
while(scanf("%d",&n),n)
printf("%d %d\n",n,a[n]);
return 0;
}
测试数据:
1
1 0
45
45 2
100
100 5
200
200 13
1000
1000 82
2000
2000 174
5000
5000 468
4567
4567 427
7891
7891 764
100000
100000 10394
500000
500000 52755
1000001
1000001 105753
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值