题目描述
素数的定义:对于一个大于1的正整数,如果除了1和它本身没有其他的正约数了,那么这个数就称为素数。例如,2,11,67,89是素数,8,20,27不是素数。
半素数的定义:对于一个大于1的正整数,如果它可以被分解成2个素数的乘积,则称该数为半素数,例如6是一个半素数,而12不是。
你的任务是判断一个数是否是半素数。
输入
输入文件中有多个测试数据,每个测试数据包含一个整数N,2<=N<=1,000,000。
输出
对每个测试数据,如果N是半素数,则输出YES,否则输出NO。
样例输入
3
4
6
12
样例输出
NO
YES
YES
NO
思路分析
本题的意思是输入一个整数N,2≤N≤1000000,判断N是不是半素数。先求出500000以内的素数(因为最小的素数为2),共41538个。
代码实现
代码一
#include <iostream>
#include <string.h>
#include <math.h>
using namespace std;
int p[500000];
int prime[50000]; //存储500000以内的所有素数(共41538个)
int k; //500000以内素数的个数
void prime_table() //求出500000以内所有的素数
{
int i,j;
memset(p,1,sizeof(p));
p[0]=0;
p[1]=0; //数组下标为素数的值为1,其余为0
for(i=2;i<250000;i++){ //除2外所有的偶数都不是素数
p[i*2]=0;
}
for(i=9;i<500000;i+=2){ //找出奇数中的素数
int flag=0;
for(j=3;j<=sqrt(i);j+=2){
if(i%j==0){
flag=1;
break;
}
}
if(flag==1)p[i]=0;
}
k=0;
for(i=0;i<500000;i++){ //用prime数组存储素数
if(p[i]!=0){
prime[k]=i;
k++;
}
}
}
int binary_search(int a[],int n,int goal){ //二分查找
int low=0;
int high=n-1;
int mid;
while(low<=high){
mid=(low+high)/2;
if(a[mid]==goal)return mid;
if(a[mid]>goal)high=mid-1;
if(a[mid]<goal) low=mid+1;
}
return -1;
}
int main()
{
int n,i;
prime_table();
while(scanf("%d",&n)!=EOF){
int flag=0;
for(i=0;i<k;i++){
if(prime[i]>sqrt(n))break; //prime[i]为素数
if((n%prime[i]==0)&&binary_search(prime,k,n/prime[i])!=-1){
//判断prime[i]是否为n的因子及其另一个因子是否为素数
flag=1;
}
if(flag==1)break;
}
if(flag==0)cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
return 0;
}
代码二
#include <iostream>
#include <string.h>
#include <math.h>
using namespace std;
int p[500000];
int prime[500000];
int k;
void prime_table() //求出500000以内的所有素数
{
int i,j;
memset(p,1,sizeof(p));
p[0]=0;
p[1]=0;
for(i=2;i<=1000;){ //对所有小于1000的素数,删除他们的倍数
for(j=i+i;j<=500000;j+=i){
p[j]=0; //删除i所有的倍数
}
for(i++;!p[i];i++); //找下一个素数
}
k=0;
for(i=0;i<500000;i++){
if(p[i]!=0){
prime[k]=i;
k++;
}
}
}
int binary_search(int a[],int n,int goal){
int low=0;
int high=n-1;
int mid;
while(low<=high){
mid=(low+high)/2;
if(a[mid]==goal)return mid;
if(a[mid]>goal)high=mid-1;
if(a[mid]<goal) low=mid+1;
}
return -1;
}
int main()
{
int n,i;
prime_table();
while(scanf("%d",&n)!=EOF){
int flag=0;
for(i=0;i<k;i++){
if(prime[i]>sqrt(n))break;
if((n%prime[i]==0)&&binary_search(prime,k,n/prime[i])!=-1){
flag=1;
}
if(flag==1)break;
}
if(flag==0)cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
return 0;
}
以上两种代码仅为找500000以内的所有素数时代码有所不同。