POJ 3292:Semi-prime H-numbers 筛选数

Semi-prime H-numbers
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 8216   Accepted: 3556

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

题意是有一个数的集合 {4n+1},叫做H-numbers,这个集合里面的运算是封闭的。如果H-numbers里面的数如果只能整除1和本身(排除1),那这个数就是H-primes。其余的是H-composites,这里面包括了H-semi-primes,H-semi-primes的意思是它本身是合数,但是它的两个因子都是H-primes。

求在给出的1到h数之间,有多少个H-semi-primes这样的数。

很好玩的筛选,总是在群里看到什么什么筛选,一直都不明白怎么玩这个筛选,但其实仔细想想,之前自己搞质数的时候已经用到了这些筛选的玩法了。这次只不过弄到台面上来了。

首先把所有集合中的数(即4n+1)都标定为质数,然后有两个质数的乘积就标定为H-semi-primes,设为1。如果不是两个质数的乘积那就标定为H-composites,设为2。这样扫了一遍之后,为0的自然是质数,为1的就是H-semi-primes,为2的就是H-composites。最后统计一遍得到结果。

代码:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <cstring>
#pragma warning(disable:4996)
using namespace std;

int h[1000002];

void init()
{
	int i, j, multi;

	memset(h, 0, sizeof(h));
	for (i = 5; i <= 1000001; i = i + 4)
	{
		for (j = 5; j <= 1000001; j = j + 4)
		{
			multi = i*j;
			if (multi > 1000001)
				break;
			if (h[i] == 0 && h[j] == 0)
				h[multi] = 1;
			else
				h[multi] = -1;
		}
	}
	int count = 0;
	for (i = 1; i <= 1000001; i++)
	{
		if (h[i] == 1)
			count++;
		h[i] = count;
	}
}

int main()
{
	//freopen("i.txt","r",stdin);
	//freopen("o.txt","w",stdout);
	
	int x;
	init();
	
	while (cin >> x&&x)
		cout << x << " " << h[x] << endl;

	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted on 2015-10-27 22:14  光速小子  阅读(378)  评论(0编辑  收藏  举报

导航