POj  3292 Semi-prime H-numbers

来源:互联网 发布:微博域名怎么改 编辑:程序博客网 时间:2024/04/29 19:29
Semi-prime H-numbers
Time Limit: 1000MSMemory Limit: 65536KTotal Submissions: 5400Accepted: 2209

Description

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

An H-number is a positive number whichis one more than a multiple of four: 1, 5, 9, 13, 17, 21,... arethe H-numbers. For this problem we pretendthat these arethe only numbers.The H-numbers are closed undermultiplication.

As with regular integers, we partitionthe H-numbers intounits, H-primes,and H-composites. 1 is the only unit.An H-number h is H-primeif it is not the unit, and is the product oftwo H-numbers in only one way: 1× h. The rest of the numbersare H-composite.

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

Your task is to count the numberof H-semi-primes.An H-semi-prime isan H-number which is the product of exactlytwo H-primes. Thetwo H-primes may be equal or different. Inthe example above, all five numbersare H-semi-primes. 125 = 5 × 5 × 5 is notan H-semi-prime, because it's the productof 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 shouldnot be processed.

Output

For eachinputted H-number h,print a line stating h andthe number of H-semi-primes between 1and h inclusive, separatedby one space in the format shown in the sample.

Sample Input

21 857890

Sample Output

21 085 5789 62

Source

Waterloo LocalContest, 2006.9.30

唉,崩溃啊,差点儿超内存,32ms,9352K,
打表,记下所有“素数”,然后再打表记下个数,最后输出。
代码和测试数据如下:
#include<stdio.h>
intprm[1100008],hnum[1100008],a[1100008]={0},qun[1100008]={0};
__int64q;
intmain()
{
intm,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]);
}
return0;
}
这是学长的代码,超简单,唉,学长就是学长啊!
#include<stdio.h>
#include<string.h>
#define N1000002
intflag[N],a[N];
intmain()
{
inti,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]);
return0;
}
测试数据:
1
10
45
452
100
1005
200
20013
1000
100082
2000
2000174
5000
5000468
4567
4567427
7891
7891764
100000
10000010394
500000
50000052755
1000001
1000001105753