Semi-prime H-numbers
Time Limit: 1000MS | | Memory Limit: 65536K |
Total Submissions: 5400 | | Accepted: 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