C语言编程习题Day1
目录
习题一:喝汽水问题
习题二:打印菱形
习题三:打印水仙花数
习题四:计算求和
习题一:喝汽水问题
喝汽水,1瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,可以喝多少汽水?
思路:
首先要明白题目规则,题目说:1元1瓶汽水,2个空瓶又可以换1瓶汽水,我们可以先算5元的,从简单的
算起,在以此类推
假设我们有5元,也就意味着我们就有了5瓶汽水,喝完之后也就有5个空瓶
1.初始化变量
int total = money; // 总喝的数量 = 直接买的 5 瓶(total=5) int empty = money; // 空瓶数 = 直接买的 5 瓶喝完的空瓶(empty=5)
money : 钱
total : 总共喝汽水的数量
empty : 空瓶子的数量
2.循环兑换逻辑
while (empty > 1){total = total + empty / 2; //用空瓶数除以2,得到“能换的新汽水数”,直接加到总数量empty = empty / 2 + empty % 2; //兑换后,空瓶 =兑换消耗的空瓶( empty/2 ) + 兑换剩下的空瓶( empty%2 )}
只要空瓶数 >1,就继续兑换:
第一次循环:
total += empty / 2 → total = 5 + 5/2 = 5+2=7 (用 5 个空瓶换 2 瓶,喝了 2 瓶)empty = empty / 2 + empty % 2 → empty = 5/2 + 5%2 = 2 + 1 = 3 (换完剩 2 个空瓶,加之前没
用到的 1 个,共 3 个空瓶)
第二次循环:
total += 3/2 = 1 → total = 7 + 1 = 8 (用 3 个空瓶换 1 瓶,喝了 1 瓶)
empty = 3/2 + 3%2 = 1 + 1 = 2 (换完剩 1 个空瓶,加之前没用到的 1 个,共 2 个空瓶)
第三次循环:
total += 2/2 = 1 → total = 8 + 1 = 9 (用 2 个空瓶换 1 瓶,喝了 1 瓶)
empty = 2/2 + 2%2 = 1 + 0 = 1 (换完剩 1 个空瓶,无法继续兑换,循环结束)
最终 total = 9 ,即 5 元最多能喝 9 瓶。9 11 19
所以这道题的核心思路就理出来了,下来我们展示完整代码:
#include<stdio.h>int Total(int money) //用total函数封装代码的核心逻辑
{int total = money;int empty = money;while (empty > 1){total = total + empty / 2;empty = empty / 2 + empty % 2;}return total;
}int main()
{ //在main函数中调用total函数printf("%d\n",Total(5));printf("%d\n", Total(6));printf("%d\n", Total(20));
}
输出结果:
9
11
19
习题二:打印菱形
用C语言在屏幕上输出以下图案:
思路:
首先先观察这个菱形图案,一共有13行,每行有空格和*组成,其次还要知道所有*是连续排列的,
*之间没有空格,空格是每行*两侧的空格缩进。
我们可以讲这13行分为上下两部分,上半部分和下半部分。
1. 上半部分:逐行增加星号数量,同时减少空格数量,形成“金字塔”形状。
2. 下半部分:逐行减少星号数量,同时增加空格数量,形成“倒金字塔”形状。
3. 核心依赖:通过嵌套循环控制空格数和星号数的动态变化。
上半部分打印( for (控制行数(从 0 到 6,共 7 行),每行需处理空格和星号:
空格逻辑 :( for (int j = 0; j < line - 1 - i; j++) ):
每行空格数 = line - 1 - i ,随 i 增大而减少。
- i=0 :空格数 = 7-1-0=6 → 打印 (6 个空格)
- i=1 :空格数 = 7-1-1=5 → 打印 (5 个空格)
- ... 以此类推,直到 i=6 :空格数 = 7-1-6=0 → 无空格。星号逻辑 :( for (int k = 0; k < 2 * i + 1; k++) ):
每行星号数 = 2*i + 1 ,随 i 增大而增加。
- i=0 :星号数 = 2*0+1=1 → 打印 *
- i=1 :星号数 = 2*1+1=3 → 打印 ***
- ... 以此类推,直到 i=6 :星号数 = 2*6+1=13 → 打印 *************
下半部分打印( for (int i = 0; i < line - 1; i++) )
循环变量 i 控制行数(从 0 到 5,共 6 行),同样处理空格和星号:
空格逻辑 :( for (int j = 0; j < i + 1; j++) ):
每行空格数 = i + 1 ,随 i 增大而增加。
- i=0 :空格数 = 0+1=1 → 打印 (1 个空格)
- i=1 :空格数 = 1+1=2 → 打印 (2 个空格)
- ... 以此类推,直到 i=5 :空格数 = 5+1=6 → 打印 (6 个空格)
星号逻辑 :( for (int k = 0; k < (line - 1 - i) * 2 - 1; k++) ):
每行星号数 = (line - 1 - i) * 2 - 1 ,随 i 增大而减少。
- i=0 :星号数 = (7-1-0)*2-1=11 → 打印 ***********
- i=1 :星号数 = (7-1-1)*2-1=9 → 打印 *********
- ... 以此类推,直到 i=5 :星号数 = (7-1-5)*2-1=1 → 打印 *
1. 变量 line 的作用:
控制菱形的总行数(上半部分 line 行,下半部分 line-1 行,总高度 2*line-1 )。
若 line=7 ,菱形总高度 = 2*7-1=13 行(与题目图案行数一致)。
2. 空格与星号的规律:
- 上半部分:空格数递减、星号数递增,形成“正三角”。
- 下半部分:空格数递增、星号数递减,形成“倒三角”。
- 数学本质:利用 i 的线性变化,通过线性公式(如 2*i+1 、 (line-1-i)*2-1 )控制数量变化。
3. 循环边界的设计:
- 上半部分循环 i < line (覆盖 0~line-1 ,共 line 行)。
- 下半部分循环 i < line-1 (覆盖 0~line-2 ,共 line-1 行)。
- 这样设计保证“上半部分高度 = line,下半部分高度 = line-1”,最终拼接成完整菱形。
完整代码:
void Funcction(int line)
{//处理上半部分for (int i = 0;i < line;i++){//1.先打印空格for (int j = 0;j < line - 1 - i;j++){printf(" ");}//2.打印星号for (int k = 0;k < 2 * i + 1;k++){printf("*");}printf("\n");}//处理下半部分for (int i = 0;i < line - 1;i++){//1.先打印空格for (int j = 0;j < i + 1;j++){printf(" ");}//2.打印星号for (int k = 0;k < (line - 1 - i) * 2 - 1;k++){printf("*");}printf("\n");}}int main()
{Funcction(7);return 0;
}
输出结果:
* // i=0(上半部分)*** // i=1(上半部分)***** // i=2(上半部分)******* // i=3(上半部分)********* // i=4(上半部分)*********** // i=5(上半部分)
************* // i=6(上半部分)*********** // i=0(下半部分)********* // i=1(下半部分)******* // i=2(下半部分)***** // i=3(下半部分)*** // i=4(下半部分)* // i=5(下半部分)
这道题思路较难,希望大家能好好理解!
习题三:打印水仙花数
求出0~100000之间的所有“水仙花数”并输出。
“水仙花数”是指一个n位数,其各位数字的n次方之和确好等于该数本身,如:153=1^3+5^3+3^3,则153是一个“水仙花数”。
思路:
代码目的是遍历 0 到 100000 的所有数,筛选出水仙花数并输出。
根据水仙花数定义: n 位数的每一位数字的 n 次方之和,等于该数本身(如 153 是 3 位数, 1³ + 5³ + 3³ = 153 )。
所以对于任意一个数来说,我们必须得到组成这个数字的每一位数,并且还要知道这个数字是由几位数组成的,这是本题的关键!
1. 遍历 0~100000 的所有数
for (int i = 0; i < 100000; i++) { int count = 0; // 记录数字的「位数」int tmp = i; // 临时变量,用于分解数字的每一位 ...... }
2. 计算数字的「位数」
while (tmp != 0) { count++; // 每循环一次,位数 +1tmp = tmp / 10; // 去掉个位数字(如 153 → 15 → 1 → 0)
3. 重新赋值 tmp,准备分解每一位
tmp = i; int sum = 0; // 存储「各位数字的 n 次方和」
4. 分解数字,计算次方和
while (tmp != 0) { int digit = tmp % 10; // 取个位数字(如 153 → 3 → 5 → 1)sum += pow(digit, count); // 累加:digit^count tmp = tmp / 10; // 去掉已处理的个位数字
5. 判断是否为水仙花数
if (sum == i) { printf("%d\n", i); // 满足条件则输出 }
1. 计算位数( count ):
- 通过 while (tmp != 0) 循环,每次 tmp / 10 去掉个位, count++ 统计循环次数,得到数字的位数。
例: i=153 → tmp=153→15→1→0 → count=3 (3 位数 )。
2. 分解数字,计算次方和( sum ):
- 重新赋值 tmp = i ,通过 tmp % 10 取个位数字(如 153 → 3)。
- 用 pow(digit, count) 计算该位数字的 count 次方(如 3³ ),累加到 sum 。
- 再通过 tmp / 10 去掉已处理的个位,继续分解下一位(如 153 → 15 → 1 )。
3. 判断与输出:
- 若 sum == i ,说明“各位数字的 n 次方和等于自身”,判定为水仙花数并输出。
完整代码:
水仙花数
#include<math.h>
void Funcction()
{for (int i = 0;i < 100000;i++){int count = 0;int tmp = i;while (tmp != 0){count++;tmp /= 10;}tmp = i;int sum = 0;while (tmp != 0){int digit = tmp % 10;sum += pow(digit, count);tmp /= 10;}if (sum == i){printf("%d\n", i);}}
}int main()
{Funcction();
return 0;
}
习题四:计算求和
求Sn=a+aa+aaa+aaaa+aaaaa的前5项之和,其中a是一个数字,
例如:2+22+222+2222+22222
思路:
计算一个由数字 a 组成的数列的前 n 项和,数列的每一项是由 a 重复组成的数(比如 a=2 , n=3 时,数列是 2 、 22 、 222 ,和为 2 + 22 + 222 )
这道题我们和前面的题一样,用一个函数封装这个求和的核心逻辑
1. 函数定义与参数
int Function(int n, int a)
- n :表示数列的项数(即要计算前几项的和)。
- a :表示组成每一项的数字(比如 a=2 ,则每一项由 2 组成 )。2. 变量初始化
int sum = 0; int tmp = 0;
- sum :用于存储数列前 n 项的和,初始化为 0 。
- tmp :用于构建每一项的数值,初始化为 0 。3. 构建数列并求和的循环
for (int i = 0; i < n; i++) {tmp = tmp * 10 + a;sum += tmp; }
- 循环 n 次,每次循环构建一项数列的数值并累加到 sum 中:
- tmp = tmp * 10 + a :这一步是核心逻辑。第一次循环时, tmp 初始为 0 ,执行后 tmp = 0 * 10 + a = a (比如 a=2 ,则 tmp=2 ,对应数列第一项 2 );第二次循环, tmp = 2 * 10 + 2 = 22 (对应数列第二项 22 );第三次循环, tmp = 22 * 10 + 2 = 222 (对应数列第三项 222 ),以此类推,每次在之前的数基础上后面拼接一个 a 。
- sum += tmp :把每次构建好的数列项数值加到 sum 中,实现求和。
完整代码:
int Funcction(int n, int a)
{int sum = 0;int tmp = 0;for (int i = 0;i < n;i++){tmp = tmp * 10 + a;sum += tmp;}return sum;
}int main()
{printf("%d\n", Funcction(1, 2));printf("%d\n", Funcction(2, 2));printf("%d\n", Funcction(3, 2));printf("%d\n", Funcction(5, 2));
}
输出结果:
2 //Function(1, 2) :计算 n=1 、a=2 时的和,即只有一项 2 ,输出 2
24 //Function(1, 2) :计算 n=1 、a=2 时的和,即只有一项 2 ,输出 2
246 //Function(3, 2) :计算 n=3 、a=2 时的和,即 2 + 22 + 222 = 246 ,输出 246
24690 //Function(5, 2) :计算 n=5 、a=2 时的和,即 2 + 22 + 222 + 2222 + 22222 = 24690 , 输出 24690
以上便是这四道题的解题思路和完整代码,可能还是有点难度,当然每道题可能会有多个解题思路
和方法。大家可以继续探索研究。这也是小编在博客中第一次写编程习题,如果有不当的地方欢迎
在评论去指出,也希望大家多多包涵!