您的位置:首页 > 其它

POj  3292 Semi-prime H-numbers

2012-12-05 17:09 483 查看
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
Waterloo Local
Contest, 2006.9.30

唉,崩溃啊,差点儿超内存,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
);
}
return
0;
}
这是学长的代码,超简单,唉,学长就是学长啊!

#include<stdio.h>
#include<string.h>
#define N
1000002
int
flag
,a
;
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
);
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: