题目:
若一个合数的质因数分解式逐位相加之和等于其本身逐位相加之和,则称这个数为 Smith 数。如:4937775=3*5*5*65837,而3+5+5+6+5+8+3+7=42,4+9+3+7+7+7+5=42,所以4937775是 Smith 数。求给定一个正整数 N,大于 N 的最小 Smith 数。
输入:若干个 case ,每个 case 一行代表正整数 N,输入 0 表示结束。
输出:大于 N 的最小 Smith 数。
输入样本
4937774
0
输出结果
4937775
刚看到这道题的时候感觉挺蒙的,我主要迷这两点:
1.什么是合数?
2.怎么求一个数的所有质因子?
百度了一下合数,原来除了质数,其他的就是合数。被这个名字给骗了。1既不是质数也不是合数。
然后我又陷入了深思,怎么求一个数的质因子???
其实这一点很好求!
举个例子:100
让100除2,看看能不能除尽,如果能除尽,就除。此时100变成了50
然后50除2,看看能不能除尽,如果能除尽,就除。此时50变成了25
然后25除2,看看能不能除尽,如果能除尽,就除。显然除不尽,那么2就要变成3
然后25除3,看看能不能除尽,如果能除尽,就除。显然除不尽,那么3就要变成4
然后25除4,看看能不能除尽,如果能除尽,就除。显然除不尽,那么4就要变成5
然后25除5,看看能不能除尽,如果能除尽,就除。此时25变成5
然后5除5,看看能不能除尽,如果能除尽,就除。此时5变成1
判断最终值为 1 了,证明除到头了,结束循环
那么 100 求到的质因子就为 2 2 5 5。
有一个细节:从最小的数 2 开始除,一旦 不能被 2 整除,那么 4 6 8 10 等等都不能被整除,也就是把非质数都已经过滤到了。
下面给大家放一段 C 语言代码:
#include <stdio.h>
int sum(int n)
{//计算一个数各位和并返回
int sum=0;
while(n>0){
sum+=n%10;
n/=10;
}
return sum;
}
bool smith(int n)
{//求 n 是否是 Smith 数
int i=2,sq = n/2,sumn=sum(n),sumt=0;
while(i<=sq)
{
if(n%i==0){
n=n/i;
sumt+=sum(i);
continue;
}
i++;
}
if(sumn==sumt)
return true;
return false;
}
int main()
{//主函数
int n,i;
scanf("%d",&n);
while(n!=0){
for(i=++n;;i++){
if(smith(i)){
printf("%d \n",i);
break;
}
}
scanf("%d",&n);
}
return 0;
}
这个算法的时间复杂度为 O(n),因为主算法就一层循环。如果有比我还要精简的算法欢迎大家留言分享。