
本文共 4063 字,大约阅读时间需要 13 分钟。
2.5 注释与习题
好了,又到了我们最爱的做题时间,看题:
2-1 水仙花数
输出 100-999 种所有的水仙花数,若三位数ABC满足ABC=A3+B3+C3,则称其为水仙花。
分析:首先,我们可以很轻松的看出可以用循环结构去解决这道题(废话,整个第二章就讲的循环),那具体怎么循环呢,这里介绍两种方法。
第一种:将100-999每一个三位数循环一遍,每次循环将三位数的个位十位百位分离出来进行检验。
代码如下:#include#include int main(){ for (int i=100;i<=999;i++){ int gw,sw,bw;//个位,十位,百位 gw=i%10; sw=i%100/10; bw=i/100; if (pow(gw,3)+pow(sw,3)+pow(bw,3)==i)//pow不懂的请回1.1 printf("%d\n",i); } return 0;}
第二种:对个位十位百位分别进行循环,将个位十位百位组合成一个三位数
代码如下:#include#include int main(){ for (int i=1;i<=9;i++)//百位的循环 for (int j=0;j<=9;j++)//十位的循环 for (int k=0;k<=9;k++)//个位的循环 if (100*i+10*j+k==pow(i,3)+pow(j,3)+pow(k,3))//水仙花的判定,100*i+10*j+k即为三位数ijk printf("%d%d%d\n",i,j,k); return 0;}
结果和上面一个代码是一样的
2-2 韩信点兵
相传韩信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排、五人一排、七人一排地变换队形,而他每次只掠一眼队伍的排尾就知道总人数了。输入3个非负整数a,b,c ,表示每种队形排尾的人数(a<3,b<5,c<7),输出总人数的最小值(或报告无解)。已知总人数不小于10,不超过100 。
样例输入:
2 1 6 2 1 3 样例输出 Case 1:41 Case 2:No answer分析:这道题的题面看起来非常的少,实际分析一下,就是每次输入三个数x,y,z,要求找到10-100内除以3余数为x,除以5余数为y,除以7余数为z的数,如果找不到就输出No answer。于是我们只要将10-100内的正整数从小到大依次循环判定,找到符合条件的就输出下来,然后跳出循环即可。
但是大家在自己编写的时候肯定发现了一个非常严重的问题,这个循环它没说什么时候结束啊!这里提供一个解决的方法。
代码如下:#includeint main(){ int x,y,z,tot=0;//tot为输出Case后面的计数器 bool flag;//用于判断循环中是否找到了这样的数 while (scanf("%d%d%d",&x,&y,&z)){ //对于这一类没有说明什么时候循环的结束的问题,我们可以把循环里面输入的代码写在这个小括号内 flag=false;//每次循环前都还没找到,所以flag赋值为false tot++; printf("Case%d: ",tot);//格式 for (int i=10;i<=100;i++){ //从10开始找 if (i%3==x&&i%5==y&&i%7==z){ printf("%d\n",i); flag=true; break;//找到了就跳出循环 } } if (flag==false)//始终没有找到怎么办 printf("No answer\n"); } return 0;}
至于有的人会问,bool型比起int型有什么好处呢,我也可以定义一个int型,通过0和1的转换进行正确和错误的判断啊。
(事实上具体的好处我也不太清楚,我只知道bool型占用的内存比int小很多,可以偷一点内存¥_¥)2-3 倒三角形
输入正整数n<=20,输出一个n层的倒三角形。
(例子打不出来,很烦)分析:这是一个比较简单的图形打印的问题,就是说对于这个图形而言,第i层有2(n-i)+1个指定符号。输出完连续的这些符号,再输出一个换行符输出下一个,这么理解就比较简单。
#includeint main(){ int n; char c; printf("亲爱的少年你要输入什么符号搭成的倒三角形呢?"); scanf("%c",&c); printf("多少层呢?"); scanf("%d",&n); for (int i=1;i<=n;i++)//外层的循环表示想要多少层 { //接下来我们一层一层开始做 for (int j=1;j<=i-1;j++)//由于是倒着的等腰三角形,所以需要在每行前面打几个空格 printf(" "); for (int j=1;j<=2*(n-i)+1;j++)//同级的循环不用担心初始量变量名的问题 printf("%c",c); printf("\n");//光标转移至下一行 } return 0;}
结果如下:

2-4 子序列的和
输入正整数n和m (n<m<106),输出 1/n2+1/(n+1)2·······+1/m2 保留五位小数的值。输入包含多组数据。结束标记为n=m=0
样例:2 4
65536 655360 0 0样例输出:
Case 1:0.42361 Case 2:0.00001分析:循环的结构比较简单,就是从n到m,至于他说的陷阱我并没有发现,大家如果有发现的可以告诉我一下
代码如下:
#includeint main(){ int n,m,x=0; do { scanf("%d%d",&n,&m); double sum=0; if(n!=0&&m!=0) x++; else break; for(;n<=m;n++) sum+=(1.00000/n)*(1.00000/n); printf("Case %d: %.5lf\n",x,sum); } while(n!=0&&m!=0); return 0;}
(CV了一下别人的代码,发现每个人的习惯差别还是很大的,像这个代码,如果是我写,就会用while true 然后在里面用break,他这个代码,实际上把循环限定条件判断重复写了两遍了)
2-5 分数化小数
输入正整数a,b,c,输出a/b精确到小数点后c位的结果。c<=100。输入包含多组数据,结束标记为a=b=c=0。
样例就不给你们看了,和前面的格式差不多。
分析:这道题乍一看和2-4差不多,还没人家难,事实上仔细观察,c最大可以取到100,而双精度浮点型都无法取到小数点后这么多位的结果。事实上,这道题用到了高精度的思想。这里提供一下代码让大家稍微了解一下。
#includeint main(){ int a,b,c,tot=0; while (true){ scanf("%d%d%d",&a,&b,&c); tot++; printf("Case %d:",tot); printf("%d.",a/b);//先输出整数部分 a=a%b; for (int i=1;i<=c;i++){ //一位一位输出小数点之后的 a*=10;//小学打竖式还会吧,这叫借0 printf("%d",a/b); a=a%b; } printf("\n"); } return 0;}
其实就是打竖式,不过是在计算机上打竖式,如果想要了解高精度运算的,请自行百度,这里不做赘述(太麻烦了= =)。
2-6 排列
用1,2,3······9 组成三个三位数,abc,def,ghi,每个数字恰好使用一次,且满足abc:def:ghi=1:2:3。输出所有满足的结果。
分析:参考2-1的两种处理方法,我采用第一种进行讲解(第二种进行解决的话涉及到函数递归方面的知识)
代码如下:
#includeint main(){ for (int i=100;i<=333;i++){ int he=45,chengji; chengji=1*2*3*4*5*6*7*8*9; //这九个数的和位45无法判断,这九个数是否为1-9,于是我们继续判断他们的乘积 int gw1,sw1,bw1;//abc的个位十位百位 gw1=i%10; sw1=i%100/10; bw1=i/100; int gw2,sw2,bw2;//def的个位十位百位 gw2=(i*2)%10; sw2=(i*2)%100/10; bw2=(i*2)/100; int gw3,sw3,bw3;//ghi的个位十位百位 gw3=(i*3)%10; sw3=(i*3)%100/10; bw3=(i*3)/100; if (gw1+sw1+bw1+gw2+sw2+bw2+gw3+sw3+bw3==he&&gw1*sw1*bw1*gw2*sw2*bw2*gw3*sw3*bw3==chengji) printf("%d %d %d\n",i,i*2,i*3); } return 0;}
我会在下一章介绍这道题用数组做的其他方法。
发表评论
最新留言
关于作者
