Humble Numbers HDU - 1058

Problem
如果一个数的所有质因子全部由2, 3, 5, 7中的任意多个组成, 那我们把这个数称为H数. 比如: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 24, 25, 27 是前 20 个H数

指出第n个H数是多少.

Input
多组输入. 每组输入包含一个正整数 n (1 <= n <= 5842).

n = 0 时结束输入.

Output
对于每组输入, 输出 “The nth humble number is number.”.
注意 "nth"的词尾应根据整数 n 的序数词词尾而改变.
Sample Input

1
2
3
4
11
12
13
21
22
23
100
1000
5842
0

Sample Output

The 1st humble number is 1.
The 2nd humble number is 2.
The 3rd humble number is 3.
The 4th humble number is 4.
The 11th humble number is 12.
The 12th humble number is 14.
The 13th humble number is 15.
The 21st humble number is 28.
The 22nd humble number is 30.
The 23rd humble number is 32.
The 100th humble number is 450.
The 1000th humble number is 385875.
The 5842nd humble number is 2000000000.

//p:problem a:answer

p:什么是h数(即humble number)?

a:H数是指:仅包含质因子2,3,5,7的数。

p:什么是质因子?

a:质因子(或质因数)在数论里是指能整除给定正整数的质数。

个人对该题目的理解:循环输入n,求出第n个h数,并输出,直到n=0时结束运行

首先我想到的是求解除所有的h数并给其排序,然后输入n的时候再到排完序的数组中寻找,然而我的内存炸裂了

wa代码

#include<stdio.h>
int ishumble(int n) { //用于判断是否为h数字
	while(n%2==0) {
		n/=2;
	}
	while(n%3==0) {
		n/=3;
	}
	while(n%5==0) {
		n/=5;
	}
	while(n%7==0) {
		n/=7;
	}
	if(n==1) {
		return 1;
	} else {
		return 0;
	}
	//这里用循环能还好的判断是否为2,3,5,7组成
	//但是接下来的解答就一定需要用到遍历,就很难受,花的时间应该很多
}
int main() {

	int n;
	long long num[5843]= {0};
	int i=0;
	for(i=1; i<=5842; i++) {
		if(ishumble(i)==1) {
			num[i]=1;
		}
	}//如果是h数那就给他个1
	int j=1;
//对是h数的数再进行排列
	for(i=0; i<5842; i++) {
		if(num[i]==1) {
			num[i]=j;
			j++;
		}
	}
	long long temp;
	long long temp_in;
	for(i=0; i<5842; i++) {
		if(num[i]!=0) {
			temp_in=num[i];
			temp=num[temp_in];
			num[temp_in]=i;
			num[i]=temp;
		}**//问题就出现在这里,我的数组开的不够大,也不能开那么大的,在n=5842时,它是2000000000,我知道接下来肯定是错了但还是蹭完了**
	}//这个时候num的下标指代的就是第几个出现,而里面的值是哪个数字

	while(scanf("%d",&n)&&n!=0) {
//		if(n==0){
//			break;
//		}
		if(n==1) {
			printf("The 1st humble number is 1.");
			continue;
		} else {
			if(n%10==1&&n%100!=11) {
				printf("The %dst humble number is %d.",n,num[n]);
			} else if(n%10==2&&n%100!=12) {
				printf("The %dnd humble number is %d.",n,num[n]);
			} else if(n%10==3&&n%100!=13) {
				printf("The %drd humble number is %d.",n,num[n]);
			} else {
				printf("The %dth humble number is %d.",n,num[n]);
			}
		}
	}
	return 0;
}

以上代码在小数字的时候应该都是正确的,而数字过大时就凉了

ac代码,动态内存

# include<stdio.h>
# define MAX 5842
long long num[MAX+1];
long long min(long long a,long long b,long long c,long long d) {
	long long min1,min2;
	min1=a<b?a:b;
	min2=c<d?c:d;
	if(min1<=min2) return min1;
	else return min2;
}
int main() {
	int i=1,n;
	num[1]=1;
	int p2,p3,p5,p7;
	p2=p3=p5=p7=1;
	while(i<5842) {
		num[++i]=min(num[p2]*2,num[p3]*3,num[p5]*5,num[p7]*7); //此处不能写为if...else if ,因为有可能num[p2]*2==num[p3]*3==num[p5]*5==num[p7]*7
		if(num[i]==num[p2]*2) p2++;
		if(num[i]==num[p3]*3) p3++;
		if(num[i]==num[p5]*5) p5++;
		if(num[i]==num[p7]*7) p7++;
	}
	while(scanf("%d",&n)&&n!=0) {
//		if(n==0) break;
//		else {
			if(n%10==1&&n%100!=11) printf("The %dst humble number is %lld.\n",n,num[n]);
			else if(n%10==2&&n%100!=12) printf("The %dnd humble number is %lld.\n",n,num[n]);
			else if(n%10==3&&n%100!=13) printf("The %drd humble number is %lld.\n",n,num[n]);
			else printf("The %dth humble number is %lld.\n",n,num[n]);
//		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43382350/article/details/84889947