题意:
对于4*n+1(n为自然数)组成的集合,乘法在该集合中是封闭的。现规定h-prime是这个集合的数字中只有1和本身能整除的数(不含1)。其余为h合数。从h合数中划分出一部分数字,这些数是由两个h素数相乘得到的,称之为h-semi。现要求在指定1~n范围内有多少个h-semi。
做法:
先求出h-prime(类似于筛选法求素数)。
再把所有的h-prime俩俩相乘得出来的数即为h-semi。
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
using namespace std;
#define Max 1000002
int isp[Max];
int num[Max];
int ish[Max];
int numb[Max];
void isprim()
{
int i,j;
isp[1]=0;
for(i=5;i<Max;i++)
{
if(i%4==1)isp[i]=1;
}
int t;
// printf("-------\n");
t=(int)sqrt(Max*1.0);
for(i=5;i<=t;i+=4)
{
if(isp[i])
{
for(j=5;j<Max;j+=4)
{
if(i*j>Max)break;
isp[i*j]=0;
}
}
}
// printf("-------\n");
}
void nums()
{
int maxn=0;
int i,j;
for(i=0;i<Max;i++)
{
if(isp[i]==1)numb[maxn++]=i;
}
// printf("-------%d\n",maxn);
for(i=0;i<maxn;i++)
{
for(j=0;j<maxn;j++)
{
if(numb[i]*numb[j]>Max)break;
ish[numb[i]*numb[j]]=1;
}
}
// printf("-------\n");
int number=0;
for(i=0;i<Max;i++)
{
if(ish[i]==1)number++;
num[i]=number;
}
// printf("-------\n");
}
int main()
{
int n;
// printf("-------\n");
isprim();
nums();
while(scanf("%d",&n)&&n)
{
printf("%d %d\n",n,num[n]);
}
return 0;
}