关于这个练习7,说实话,是我做过的最有趣味的一个练习,没有之一。原因在于在实现题目的过程虽然艰辛,但一旦灵光乍现,就会很完美地解决问题,并且会为自己的灵感感到十分地惊喜,很值得回味。在这个练习中,尤其让我觉得十分巧妙的无非就是I题(反转数)和P题(数字反转)。其实,如果你能想到一种绝妙而其实就是数的本质的方法,就能用一个代码解决两道题。另外,对break的应用也是这个练习如此有趣的原因之一。
I(反转数)
输入一个正整数,反转该数
输入描述: 一个正整数n, (1 ≤ n ≤ 100000000)
输出描述: 输出反转n后的数。
初做此题的人可能会云里雾里:这怎么可能?但是,只要你能将原数和反转后的数比较一下,你就能明白其中的奥妙。
#include <iostream> using namespace std; int main() { int n,a=0,b; cin>>n; while(n!=0) { b=n%10; a=a*10+b; n=n/10; } cout<<a<<endl; return 0; }如何将反转前的个位数转换为反转后的千位数?这其实是一步一步来的:
b=1234%10=4;
a=0*10+4=4;
1234/10=123;
n=123;
b=123%10=3;
a=4*10+3=43;
123/10=12;
n=12;
b=12%10=2;
a=43*10+2=432;
12/10=1;
n=1;
b=1%10=1;
a=432*10+1=4321;
1/10=0(不符合循环条件,退出循环)
作为一种巧妙且高效的反转数的方法,值得记忆。
同样,作为一种反转数的方法,在负数中同样使用:
P(数字反转)
题目描述 :给定一个整数,请将该数各个位上数字反转得到一个新数。新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零(参见样例2)。
输入描述: 一个整数 N。
输出描述: 一个整数,表示反转后的新数。
其实题目描述的意思就是I题题目的意思,输入一个负数,同样也能得到正确结果:
其余的题中也有难题,例如O题(数字黑洞),但本人认为不如I题和P题耐人寻味,只要按照题目的意思坚持编写程序就可以了。
O(数字黑洞)
题目描述 :给定一个三位数,要求各位不能相同。例如,352是符合要求的,112是不符合要求的。将这个三位数的三个数字重新排列,得到的最大的数,减去得到的最小的数,形成一个新的三位数。对这个新的三位数可以重复上述过程。被奇的是,最终一定会得到495! 试试看,重新排列352,得到的最大数为532,最小数为235,它们的差是297: 变换297,得到972- 279 = 693;变换693,963-369 = 594;变换594,954-459 =495。因此,352经过4次变换得到了495。 现在,输入的三位数,你能通过编程得出,这个三位数经过多少次变换能够得到495吗?
输入描述: 输入一行,包含一个符合要求的三位数N。
输出描述: 输出一行,包含一个整数C,表示经过C次变换得到495 。
AC代码:
#include<iostream> #include<cmath> #include<iomanip> using namespace std; int main() { int num,a,b,c,max,mid,min,big,small,n=0; cin>>num; while(num!=495) { a=num/100; c=num%10; b=num/10%10; if(a>=b){max=a;min=b;} else {max=b;min=a;} if(max<c){mid=max;max=c;} else if(min>c){mid=min;min=c;} else {mid=c;} big=max*100+mid*10+min; small=min*100+mid*10+max; num=big-small; n++; } cout<<n<<endl; return 0; }总结一下,就是这个练习让我掌握了一种讲数反转的新方法,另外对于实现题目的过程需要极大的灵感和直觉,我想这也是编写程序所应有的一种品质吧。真的蛮有意思的。