1. 程式人生 > >SXYBT-0102H數(Semi-prime H-numbers)

SXYBT-0102H數(Semi-prime H-numbers)

一道很棒的數學題。

思路:先篩出“素數”,然後將“素數”兩兩相乘,枚舉出範圍以內的“合成數”,再計算字首和。最後直接輸出。

#include<iostream>
#include<cstring>
#include<cmath>
#define INF 1000001
using namespace std;
bool ip[250001],hp[250001];//ip記錄“素數”,hp記錄“合成數” 
int s[250001];//字首和
int main()
{
	int R=sqrt(INF);
	for(int i=5;i<=R;i+=4){//“素數”篩法
		if(!ip[i/4]){
			for(int j=5;i*j<=INF;j+=4) ip[i*j/4]=1;
		}
	}
	for(int i=5;i<=R;i+=4){//兩兩相乘,列舉“合成數” 
		for(int j=i;i*j<=INF;j+=4){
			if(!ip[i/4]&&!ip[j/4]) hp[i*j/4]=1;
		}
	}
	for(int i=1;i<=INF/4;i++){//計算字首和(前i個H數中的“合成數”個數) 
		s[i]=s[i-1];
		if(hp[i]) s[i]++;
	}
	while(1){
		int h;
		cin>>h;
		if(h==0) return 0;
		cout<<s[h/4]<<endl;//直接輸出 
	}
}