一、概述
1、问题描述
找出第n个“humble number”,“humble number”:只包含因子2、3、5和7的数,包括1。
2、问题链接
HDU -- Humble Numbers(ACM Step: 3.2.5)
3、问题截图
图1.1 问题截图
二、算法思路
想了一会发现,只需要找出那些由因子2、3、5、7组合成的数就可以了,如,2,3,5,7,(2,2),(2,3),...
所以问题就变成如何找出所有的2、3、5、7组合数。
1. 由1个因子组成的数
只有2、3、5、7,这4种
2. 由2个因子组成的数
以2为第1个分量来找:
(2,2),(2,3),(2,5),(2,7)
以3:
(3,3),(3,5),(3,7)
以5:
(5,5),(5,7)
以7:
(7,7)
3. 由3个因子组成的数
以(2,2):
(2,2,2),(2,2,3),(2,2,5),(2,2,7)
以(2,3):
(2,3,3),(2,3,5),(2,3,7)
...
找的过程中发现,为了找出不重复的因子组合,可以这样来进行:
对于最大因子,若是2,则可以用2,3,5,7,这4个因子分别与其构成新的因子组合
若是3,则可以用3,5,7,这3个因子分别与其构成新的因子组合
5,则是5,7
7,则仅有7
所以在实现时,主动记录了最大因子,然后以因子组合数目为1作为起点(因子组合数目为1的有4个数2,3,5,7),分别检索每个因子组合的最大因子,然后以上面的规律构成新的因子组合。
并且由于这样找出的数是不具有一定的顺序的,最后需要对其进行排序,以满足题意的按序输出。
三、算法实现
#include <iostream> //for cin, cout, endl
#include <algorithm> //for sort
using std::cin;
using std::cout;
using std::endl;
using std::sort;
typedef struct Answer
{
long long n; //n for number, represent the data
int last; //max factor
}ans;
const int MAXSIZE = 5842;
const long long MAXNUM = 2000000000LL; //max num for the answer array
ans a[MAXSIZE]; //store the result for problem
bool sort_data(ans a1, ans a2)
{
if(a1.n < a2.n)
return true;
else
return false;
}
/*
* name: calculate
* description: calculate the result
* return value: void
* argument: void
*/
void calculate()
{
int i, j;
long long tmp;
a[0].n = 1;
a[0].last = 1;
a[1].n = 2;
a[1].last = 2;
a[2].n = 3;
a[2].last = 3;
a[3].n = 5;
a[3].last = 5;
a[4].n = 7;
a[4].last = 7;
//find all conbination of 2, 3, 5, 7, total is MAXSIZE
for(i=1, j=5; j<MAXSIZE; i++){
switch(a[i].last){
case 2:
tmp = a[i].n * 2;
if(tmp > MAXNUM)
continue;
a[j].n = tmp;
a[j++].last = 2;
case 3:
tmp = a[i].n * 3;
if(tmp > MAXNUM)
continue;
a[j].n = tmp;
a[j++].last = 3;
case 5:
tmp = a[i].n * 5;
if(tmp > MAXNUM)
continue;
a[j].n = tmp;
a[j++].last = 5;
case 7:
tmp = a[i].n * 7;
if(tmp > MAXNUM)
continue;
a[j].n = tmp;
a[j++].last = 7;
break;
default:break;
}
}
sort(a, a+MAXSIZE, sort_data); //sort the data to an increasing order
}
//print the result
void print(int n)
{
cout << "The " << n;
if(n%100==11 || n%100==12 || n%100==13)
cout << "th";
else if(n%10 == 1)
cout << "st";
else if(n%10 == 2)
cout << "nd";
else if(n%10 == 3)
cout << "rd";
else
cout << "th";
cout << " humble number is ";
cout << a[n-1].n ;
cout << ".\n";
}
int main()
{
int n;
calculate();
while(cin>>n && n!=0){
print(n);
}
return 0;
}