【_(:з)∠)_咸_(:з)∠)_鱼_(:з)∠)_本_(:з)∠)_鱼_(:з)∠)_】
【知识梳理】


【典例分析】
【第一题】
题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
思路:动用高中的数学知识可知这是一个可以口答排列问题P(3;4)=4×3×2=24。
那么从排列的原理考虑,我们的程序实现思路大致是:
①4挑一放在第一位
②剩下的3挑一放在第二位
③剩下的2挑一放在第三位
要实现以上步骤,需要一个遍历所有三位数和筛选出无重复三位数的过程。
我们可以用循环语句来实现遍历,用判断语句来实现筛选。
#include <stdio.h> int main() { int i = 0; int a = 1; int b = 1; int c = 1; for (a = 1; a <= 4; a++) { for (b = 1; b <= 4; b++) { for (c = 1; c <= 4; c++) { if (a != b && b != c && a != c) { i++; printf("第\t%d\t个三位数\t=\t%d%d%d\n", i, a, b, c); } } } } printf("\n共有\t%d\t个三位数\n\n",i); system("pause"); return 0; }
运行结果:

做题心得:想对齐输出就用制表符\t和\n,是反斜杠“\”不是除号“/”。另外变量不初始化居然会报错欸。
【第二题】
题目:企业发放的奖金根据利润提成。
利润(I)低于或等于10万元时,奖金可提10%;
利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%;
20万到40万之间时,高于20万元的部分,可提成5%;
40万到60万之间时高于40万元的部分,可提成3%;
60万到100万之间时,高于60万元的部分,可提成1.5%;
高于100万元时,超过100万元的部分按1%提成。
从键盘输入当月利润I,求应发放奖金总数?
思路:这道题是典型的分情况讨论问题。
我们理所当然的想到了利用判断语句来实现我们的目的。
#include <stdio.h> int main() { //录入数据 float I; printf("请输入当月利润:"); scanf_s("%f", &I); //基础提成 float Commission10 = 100000 * 0.1; float Commission20 = Commission10 + 100000 * 0.075; float Commission40 = Commission20 + 200000 * 0.05; float Commission60 = Commission40 + 200000 * 0.03; float Commission100 = Commission60 + 400000 * 0.015; //进行判断得到总提成 float Commission; if (I < 100000) { Commission = I * 0.1; } else if (I < 200000) { Commission = Commission10 + I * 0.075; } else if (I < 400000) { Commission = Commission20 + I * 0.05; } else if (I < 600000) { Commission = Commission40 + I * 0.03; } else if (I < 1000000) { Commission = Commission60 + I * 0.015; } else { Commission = Commission100 + I * 0.01; } printf("你本月的提成是:%f\n\n", Commission); system("pause"); return 0; }
运行结果:

做题心得:vs一个项目可以写多个源程序,只不过写完一个需要把上一个禁止生成,否则主函数会冲突的。另外用scanf已经不只是警告而直接报错了,要用scanf_s。
【第三题】
题目:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?
思路:这道题的关键在于读出“完平+168=完平”这条判据。
因此我们用循环可以遍历出满足上述判据的所有解。
循环上限判据可以定为“相邻两完平之差大于168”。
1 #include <stdio.h> 2 3 int main() 4 { 5 //数据初始化 6 int i = 0; 7 int j = 0; 8 int x = 0; 9 int delta = 0; 10 int difference = 0; 11 12 13 for (i = 1; difference < 168; i++) 14 { 15 //每次变i后要重新定义j和delta 16 j = i + 1; 17 delta = 0; 18 19 //寻找差为168的平方数 20 for (; delta < 168; j++) 21 { 22 delta = (j * j - i * i); 23 } 24 if (delta == 168) 25 { 26 x = i * i - 100; 27 printf("这个数可以是%d\n\n", x); 28 } 29 30 //计算上限判据 31 difference = (i + 1)*(i + 1) - i * i; 32 } 33 34 system("pause"); 35 return 0; 36 }
运行结果:

做题心得:这道题目叙述带有误导性,让人以为满足条件的解只有一个,一开始我也是解出-99就因为结束了。后来一看答案有四个解,才思考到了上限的问题。
【第四题】
题目:输入某年某月某日,判断这一天是这一年的第几天?
思路:这道题其实只需要考虑普通年和闰年。
普通年按小时候的口令,判断并计算,原理同第二题。
闰年判断出来后,给2月之后的日子+1就可以啦。
1 #include <stdio.h> 2 #include <windows.h> 3 4 int main() 5 { 6 while (1) 7 { 8 //录入数据 9 int year, month, day; 10 printf("请输入年、月、日(两两之间以一个空格隔开,按回车键结束):"); 11 scanf_s("%d %d %d", &year, &month, &day); 12 13 //普通年,按月计算基础日期 14 int January = 0; 15 int February = 0; 16 int March = 0; 17 int April = 0; 18 int May = 0; 19 int June = 0; 20 int July = 0; 21 int August = 0; 22 int September = 0; 23 int October = 0; 24 int November = 0; 25 int December = 0; 26 27 January = 31; 28 February = January + 28; 29 March = February + 31; 30 April = March + 30; 31 May = April + 31; 32 June = May + 30; 33 July = June + 31; 34 August = July + 31; 35 September = August + 30; 36 October = September + 31; 37 November = October + 30; 38 39 //普通年,按月计算日期 40 int number = 0; 41 42 if (month == 1) 43 { 44 number = day; 45 } 46 else if (month == 2) 47 { 48 number = January + day; 49 } 50 else if (month == 3) 51 { 52 number = February + day; 53 } 54 else if (month == 4) 55 { 56 number = March + day; 57 } 58 else if (month == 5) 59 { 60 number = April + day; 61 } 62 else if (month == 6) 63 { 64 number = May + day; 65 } 66 else if (month == 7) 67 { 68 number = June + day; 69 } 70 else if (month == 8) 71 { 72 number = July + day; 73 } 74 else if (month == 9) 75 { 76 number = August + day; 77 } 78 else if (month == 10) 79 { 80 number = September + day; 81 } 82 else if (month == 11) 83 { 84 number = October + day; 85 } 86 else if (month == 12) 87 { 88 number = November + day; 89 } 90 else 91 { 92 printf("输入错误!请重新输入!"); 93 } 94 95 //满足闰年三条件,则给2月后的日期+1 96 if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) 97 { 98 printf("\n是闰年!\n"); 99 if (month > 2) 100 { 101 number++; 102 } 103 104 } 105 106 printf("\n这是当年的第\t%d天\n\n", number); 107 system("pause>nul"); 108 } 109 110 return 0; 111 }
运行结果:

做题心得:这道题目的重点其实在于闰年判断以及闰年的输出策略。为了验证闰年逻辑是否正确,特地加入死循环语句,这样就能输入不同的日期反复调试对比。另外学了一招pause>nul,这样就不用看见“请按任意键继续...”但仍然能停下来了。
【第五题】
题目:输入三个整数x,y,z,请把这三个数由小到大输出。
思路:这道题可以把所有情况列出来。
也可以用三次if做一个简单的排序。
1 #include <stdio.h> 2 3 int main() 4 { 5 double a = 0; 6 double b = 0; 7 double c = 0; 8 double A = 0; 9 double B = 0; 10 double C = 0; 11 12 printf("请输入三个数(以空格键隔开,以回车键结束):"); 13 scanf_s ("%lf %lf %lf",&a, &b, &c); 14 15 A = a ; 16 B = b ; 17 C = c ; 18 19 if (c > a) 20 { 21 A = c; 22 B = a; 23 C = b; 24 if (b > a) 25 { 26 A = c; 27 B = b; 28 C = a; 29 if (b > c) 30 { 31 A = b; 32 B = c; 33 C = a; 34 } 35 } 36 } 37 printf("\n这三个数的从大到小的顺序是%lf %lf %lf", A, B, C); 38 39 system("pause>nul"); 40 return 0; 41 }
运行结果:

做题心得:这道排序题目可以视作算法的入门,学会用指针数组之后可以用更高级的方法处理更多数据(然而我把排序方法忘光了)。
【第六题】
题目:用*号输出字母C的图案。
思路:我们不要C!我们要高级小心心!
1 #include <stdio.h> 2 3 #include <math.h> 4 5 float f(float x, float y, float z) { 6 float a; 7 a = x * x + 9.0f / 4.0f * y * y + z * z - 1; 8 return a * a * a - x * x * z * z * z - 9.0f / 80.0f * y * y * z * z * z; 9 } 10 11 float h(float x, float z) { 12 float y; 13 for (y = 1.0f; y >= 0.0f; y -= 0.001f) 14 if (f(x, y, z) <= 0.0f) 15 return y; 16 return 0.0f; 17 } 18 19 void main() { 20 float z, x, v, y0, ny, nx, nz, nd, d; 21 for (z = 1.5f; z > -1.5f; z -= 0.05f) { 22 for (x = -1.5f; x < 1.5f; x += 0.025f) { 23 v = f(x, 0.0f, z); 24 if (v <= 0.0f) { 25 y0 = h(x, z); 26 ny = 0.01f; 27 nx = h(x + ny, z) - y0; 28 nz = h(x, z + ny) - y0; 29 nd = 1.0f / sqrtf(nx * nx + ny * ny + nz * nz); 30 d = (nx + ny - nz) * nd * 0.5f + 0.5f; 31 putchar(".:-=+*#%@"[(int)(d * 5.0f)]); 32 } 33 else 34 putchar(' '); 35 } 36 putchar('\n'); 37 } 38 system("pause>nul"); 39 }
运行结果:

做题心得:这是我从网上粘来的大佬作品,思路大概是用函数勾勒边框用符号填充?
浙公网安备 33010602011771号