C/C++_循环结构程序设计练习 深藏阁楼爱情的钟 2021-09-23 21:34 422阅读 0赞 相对第一天,第二天的已经有点挑战了。例题和习题已经出现了真正的竞赛题目——仅使用简单变量和基本的顺序、分支和循环结构就可以解决很多问题。 # 习题 # 1. 水仙花数。输出100~999所有的水仙花数。ABC=A3\+B3\+C3即为水仙花数。eg:153就是水仙花数,153=13\+53\+33 2. 韩信点兵。相传韩信清点士兵从来不直接清点。只要让士兵三人一排、五人一排、七人一排地变换队形,每次只要看队尾的几个人就可以得出士兵的数量。输入包含多组数据,每组数据包含3个非负整数a,b,c,表示每种队列排尾的人数(a<3,b<5,c<7),输出为符合的人数最小值(全部不符合就输出No answer)。总人数不小于10,不超过100。输入到文件结束为止。 样例输入: 2 1 6 2 1 3 样例输出: Case 1: 41 Case 2:No answer 3. 倒三角形。输入正整数n(n<=20),输出一个n层倒三角形。例如 样例输入: 5 样例输出: ![在这里插入图片描述][20200206164505242.png] 4. 子序列的和。输入两个正整数n<m<106,输出1/n2\+1/(n+1)2\+…+1/m2,保留5位小数。输入包含多组数据,结束标记为n=m=0,提示:本题有陷阱。 样例输入: 2 4 65536 655360 0 0 样例输出: Case 1:0.42361 Case 1:0.00001 5. 分数化小数。输入正整数a,b,c,输出a/b的小数形式,精确到小数点后c位。a,b<=106,c<=100。输入包含多组数据,结束标记为a=b=c=0。 样例输入 1 6 4 0 0 0 样例输出: Case 1:0.1667 6. 排列。用1,2,3,…,9组成3个三位数abc,def和ghi,每个数字恰好使用一次,要求abc:def:ghi=1:2:3。按照abc def ghi的格式输出所有解,每行一个解。提示:不必太动脑筋。 以下的代码都是自己修改,逐步逐步写出来的,也有很多错误的地方,在论坛上也问了很多大佬才逐步修改完成的代码,谢谢那些无私教导自己的大佬。若有更好的代码,可以在评论里面分享! // 1,水仙花数 //很常见的题目了,自己大一遇到这个题目三四次了。。。 #include <stdio.h> int main() { int a, b, c; for(int i=100;i<=999;i++) { a = i/100%10; b = i/10%10; c = i%10; if(a*a*a+b*b*b+c*c*c == i) printf("%d\n", i); } return 0; } // *2,韩信点兵 #define LOCAL #include <stdio.h> int main() { #ifdef LOCAL freopen("data_1.in", "r", stdin); freopen("data_1.out" ,"w", stdout); #endif int a, b, c, temp=0 ,count=0; while(scanf("%d%d%d", &a, &b, &c) == 3) //scanf函数是输入几个数据就返回几,这里三个数据,就是scanf(...) == 3,自己一开始不会用, { temp = 0; for(int i=10;i<=100;i++) { if((i%3 == a) && (i%5 == b) && (i%7 == c)) { temp = 1; printf("Case %d: %d\n", count, i); break; } } if(temp != 1) printf("Case %d: No answer\n", ++count); } return 0; } // 3.倒三角形 //以输入5为例,可以找出规律。 //输出" "的规律:第i行输出i-1个 //输出"#"的规律:第i行输出(n-i)*2+1个 #include<stdio.h> int main() { int n; scanf("%d", &n); for(int i=1;i<=n;i++) { for(int j=1;j<=i-1;j++) printf(" "); for(int j=(n-i)*2+1;j>0;j--) printf("#"); printf("\n"); } return 0; } // *4.子序列的和 #include <stdio.h> int main() { int n, m, k=0; double sum = 0.0; while(scanf("%d%d", &n, &m) == 2 && (n || m)) { sum = 0.0; for(double i=n;i<=m;i++) //i若不是double类型,num计算的就是1/0了,导致sum最终输出1.#INF { double num = 1.0/(i*i); sum += num; } printf("Case %d: %.5f\n", ++k, sum); } return 0; } // 5.分数化小数 //自己觉得难点在实现保留不固定的小数位 //百度Google也没有找到合适的解决办法,只找到了C++中使用函数解决的方法。 //自己通过论坛大佬的帮助解决了这一问题,就是使用*占位符 #include <stdio.h> //#include <math.h> int main() { int a, b, c, kase=0; while(scanf("%d%d%d", &a, &b, &c) == 3 && (a || b || c)) { double num = (double)a/b; //double t = pow(10, c+1); //int n = t * num; //if(n%10 >= 5) n = n/10 + 1; //else n = n/10; printf("Case %d: %.*lf\n", ++kase, c, num); //++kase对应的是%d,c对应的是*,num对应的是%.lf,很好理解 } return 0; } // 6.排列 //下面详细说 第6题是ACM的题目,自己第一次写确实写不来,自己写的代码什么输出都没有,Google了这道题,找到了解决方法: ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0Fuc19taW4_size_16_color_FFFFFF_t_70] 这里我还是把我第一次写失败的代码截图出来吧,毕竟是自己写了很久的代码,也当是个教训了。 //错误代码 #include <stdio.h> int main() { int n1,n2,n3; for(int j=123;j<=333;j++) { int a = j/100; int b = j/10%10; int c = j%10; int d = (2*j)/100; int e = (3*j)/10%10; int f = (2*j)%10; int g = (3*j)/100; int h = (3*j)/10%10; int i = (3*j)%10; if((a==0) || (b==0) || (c==0)) continue; //自己感觉问题出在这里 if((a!=b) && (a!=c) && (a!=d) && (a!=e) && (a!=f) && (a!=g) && (a!=h) && (a!=i)) if((b!=c) && (b!=d) && (b!=e) && (b!=f) && (b!=g) && (b!=h) && (b!=i)) if((c!=d) && (c!=e) && (c!=f) && (c!=g) && (c!=h) && (c!=i)) if((d!=e) && (d!=f) && (d!=g) && (d!=h) && (d!=i)) if((e!=f) && (e!=g) && (e!=h) && (e!=i)) if((f!=g) && (f!=h) && (f!=i)) if((g!=h) && (g!=i)) if(h!=i) printf("%d %d %d\n", i, 2*i, 3*i); } return 0; } //接下来是正确的代码: #include <stdio.h> //实现输入一个三位数,将三个位置上的数字累加存入result_add,累乘存入result_mul void result(int num, int &result_add, int &result_mul) //num是传入值,其他两个是传出值,用来将传入的三位数三个组成数字累加和累乘。 { int i,j,k; i =num/100; j = num/10%10; k = num%10; result_add += i+j+k; result_mul *= i*j*k; } int main() { int i,j,k; int result_add,result_mul; for(i=123;i<=329;i++) { j = i*2; k = i*3; result_add = 0; result_mul = 1; result(i, result_add, result_mul); result(j, result_add, result_mul); result(k, result_add, result_mul); if(result_add == 45 && result_mul == 362880) //保证9个数是1到9无重叠,result_add=1+2+...+9,result_mul=1*2*...*9。 printf("%d %d %d\n", i, j, k); } return 0; } # 思考 # 题1: 修改程序,输出2,4,6,8,…,2n,每个一行。 #include <stdio.h> int main() { int n; scanf("%d", &n); for(int i=1;i<=2n;i++) printf("%d\n", i); return 0; } 1. 修改for的条件,其他不改 2. 修改循环体,其他不改 两种方法都写 // 1.修改条件的方法 for(int i = 2;i<=2*n;i+=2) //其他地方不动 // 2.修改循环体的方法 printf("%d\n",2*i); //其他地方不动 题2: 说出下面程序输出的数据 #include <stdio.h> int main() { double i; for(i=0;i!=10;i+=0.1) printf("%.1f\n", i); return 0; } 先来预测一下,我一开始认为i从0一直加0.1,加到9.9的时候,再次+0.1,然后!=条件不满足,跳出循环,输出的应该就是0到9.9的一行行的数据。 但是,我们运行后,却出现了死循环。这是因为浮点数计算有误差,9.9+0.1!=10,可能等于0.9999999什么的,从而陷入死循环,从而输出大于10的数据。这里我们也知道了,用浮点数做条件的时候不要用不等于,用小于大于这些影响还是不大的,就像上面一个练习:子序列的和,for循环里的i就是double类型(保证1/(i\*i)计算不为0)。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0Fuc19taW4_size_16_color_FFFFFF_t_70 1] 这节练习确实挺难的,但多写写,多了解一些思路应该就会了。 [20200206164505242.png]: /images/20210923/b8f7beba7f984a32817774592f4b97a5.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0Fuc19taW4_size_16_color_FFFFFF_t_70]: /images/20210923/34dc6b8e13aa40fb92513d7c7c10025d.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0Fuc19taW4_size_16_color_FFFFFF_t_70 1]: /images/20210923/9ad2516621854081b7177dc78343c24f.png
还没有评论,来说两句吧...