查找不小于所输入数据的最小Smith数
Smith数问题(20分) 题目内容: 若一个正整数的质因数分解式逐位相加之和等于其本身逐位相加之和,则称这个数为 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 数。
输入格式: 若干个正整数,一行代表一个正整数 N,以输入 0 表示结束
输出格式: 按行输出大于正整数N 的最小 Smith 数
输入样例:
4937774
200
0
输出样例:
4937775
202
1 #include <iostream> 2 #include <math.h> 3 using namespace std; 4 //按行输出大于正整数N的最小Smith数 5 6 //判断所输入的数是否为素数(诀窍:i只需循环到x的平方根即可) 7 bool isPrime(int x) { 8 int i; 9 if (x == 2 || x == 3) return true; 10 for (i = 2; i <= sqrt(x); i++) { 11 if (x%i == 0) return false; 12 } 13 return true; 14 } 15 //求各位数的和 16 int Sum(int x) { 17 int sum = 0; 18 while (x) { 19 sum += x % 10; 20 x = x / 10; 21 } 22 return sum; 23 } 24 //判断一个数是否为Smith数 25 bool isSmith(int x) { 26 int i; 27 int sumx = Sum(x); 28 int sump = 0; 29 for (i = 2; i <= x;) { 30 if ((x%i == 0) && isPrime(i)) { 31 sump += Sum(i); 32 x = x / i; 33 } 34 else { 35 i++; 36 // 因为要对找出以一个质因子后得到的除数在找质因子,而且还是要从i = 2开始 37 // i++;放在这里既解决了上述问题,也对上述除数提供了循环(主要是解决质因子重复问题) 38 } 39 } 40 if (sumx == sump) return true; 41 return false; 42 } 43 //查找不小于所输入的输的最小史密斯数 44 int Smith(int n) { 45 while (!isSmith(n)) n++; 46 return n; 47 } 48 int main() { 49 //提示输入数据 50 cout << "请依次输入所要求的的数据起始值(以最后输入0为结束标识)" << endl; 51 cout << "注:本代码只以解决问题为最终目的,不设置异常事件以及事件处理机制"<<endl; 52 cout<<"所以所以不要输入不满足条件的数(防止我下次好奇心害死猫。。。)" << endl; 53 int i = 0,n=0, X[10];//计数器,记录输入数据个数,存放输入数据 54 do { 55 cin >> X[i]; 56 i++; 57 } while (X[i - 1] != 0); 58 n = i - 1;//最后输入的0不算进来 59 for (i = 0; i < n; i++) cout << Smith(X[i]) << endl; 60 cout << endl << endl << "完结撒花!!!" << endl; 61 cout << endl << endl << "*******你看你不是做到了嘛!*******" << endl << endl; 62 return 0; 63 }
编写时问题:
1.注意质因子重复问题。
解决:第29行代码中为加入i++这一循环条件,而是在34行添加i++语句,使得若i为质因子时,还可以进行下一次判断,避免了函数重新重头遍历。
2.29行i的循环终止条件。
多次取商后的x本身有可能是质因子之一,所以必须保证i<=n,例如:200,4937774
3.29行i的循环开始条件。
刚开始取i=0,发现代码总是异常结束,最终检查后发现原因是0做除数时不成立,但系统不报错,都是泪啊。。。
4.第9行单独说明x=2和x=3的原因
发现当x=2或x=3时根本无法开始第10行的循环,所以必须要单独说明这两种情况。