学C的第二十四天【练习】

=========================================================================

 相关代码gitee自取:C语言学习日记: 加油努力 (gitee.com)

=========================================================================

接上期:
学C的第二十三天【继续深度剖析数据在内存中的存储:浮点型在内存中的存储(重点)、练习】_高高的胖子的博客-CSDN博客

========================================================================= 

                       

 练习:(重点在图片注释)

                        

1. 打印菱形

题目:

用C语言在屏幕上输出以下图案:

            

实现代码:

//打印菱形
//上半部分:空格在减少,*号在增多
#include <stdio.h>
int main()
{
	int line = 0;//上半行数
	scanf("%d", &line);//输入上半行数
	
	//菱形上半部分的打印:行数 -- line
	int i = 0;
	for (i = 0; i < line; i++)
	{
		//打印一行,先打印空格,再打印*号
		
		//打印空格:
		int j = 0;
		//上半部分空格规律:
		//			line-1-i:假设行数是7,
		//第一行打印7-1-0=6个空格;第二行打印7-1-1=5个空格……
		for (j = 0; j < line-1-i; j++)	
		{
			printf(" ");
		}

		//打印*号:
		//上半部分*号规律:
		//			2*i+1:假设行数是7,
		//第一行打印2*0+1个*号;第二行打印2*1+1个*号……
		for (j = 0; j < 2*i+1; j++)
		{
			printf("*");
		}

		//打印完后进行换行:
		printf("\n");
	}


	//菱形下半部分的打印:行数 -- line-1
	for (i = 0; i < line-1; i++)
	{
		//打印一行,先打印空格,再打印*号

		//打印空格:
		int j = 0;
		//下半部分空格规律:
		//			j<=i:假设行数是7-1=6,
		//第一行打印j=0,i=0,j<=i,1个空格;第二行打印j=0,i=1,j<=i,2个空格……
		for (j = 0; j <= i; j++)
		{
			printf(" ");
		}

		//打印*号:
		//下半部分*号规律:
		//		2*(line-1-i)-1:假设行数是7-1=6,
		//第一行打印2*(7-1-0)-1,11个*号;第二行打印2*(7-1-1)-1,9个*号……
		for (j = 0; j < 2*(line-1-i)-1; j++)
		{
			printf("*");
		}

		//打印完后进行换行:
		printf("\n");
	}


	return 0;
}

               

测试图片:

           

菱形上半部分:

                    

菱形下半部分:

                     


                      

2. 打印0-100000中的自幂数(水仙花数是其中一种)

题目:

求出0~100000之间的所有自幂数输出

自幂数是指一个n位数,其各位数字的n次方之和恰好等于该数本身

如:153=1^3+5^3+3^3,则153是一个自幂数

            

实现代码:

//打印自幂数(0-100000):
//假设 m 是一个 n位数 ,m 的 每一位的n次方之和 等于 m。
//如-- 153 = 1 ^ 3 + 5 ^ 3 + 3 ^ 3
#include <stdio.h>
#include <math.h>
int main()
{
	int i = 0;
	for (i = 0; i <= 100000; i++)
	//使用for循环产生0-100000的数
	{
		//判断i是否是自幂数:
		//1. 知道是几位数:计算i的位数 -- n
		//一个数 至少也是 一位数,所以起始 n=1
		int n = 1;
		int tmp = i;//代替i,防止后续操作改变循环变量
		//思路:i/10 --> 可以去掉一位 --> n+1 ,直到i/10==0
		while (tmp /= 10) //直到/10==0,停止循环
		{
			n++;//统计位数
		}
		
		//2. 求每一位的n次方之和
		//思路:%10 --> 取出每一位
		tmp = i;//再次替换i
		int sum = 0;//存放每位次方后的和
		while (tmp)//只要i不等于0,就继续取出每一位
		{
			sum += pow(tmp % 10, n);
			//模10 取出一位后,求出这位数的n次方,再求和
			tmp /= 10;//移至下一位
		}

		//3. 判断是不是自幂数
		if (sum == i)
		{
			printf("%d ", i);//是则进行打印
		}
	}
	return 0;
}

                   

测试图片:

                     


                      

3. 求Sn=a+aa+aaa+aaaa+aaaaa+……的前n项之和

题目:

Sn=a+aa+aaa+aaaa+aaaaa+……的前n项之和,其中a一个数字

例如:2+22+222+2222+22222+……

            

实现代码:

//计算求和
//求Sn = a + aa + aaa + aaaa + aaaaa的前n项之和,其中a是一个数字,
//例如:2 + 22 + 222 + 2222 + 22222
#include <stdio.h>
int main()
{
	int a = 0;
	int n = 0;//a的前n项
	scanf("%d %d", &a, &n); 

	//规律:a + a*10+a + ……
	//利用规律算出每一项后相加
	int i = 0;
	int sum = 0;//算出每一项后相加
	int k = 0;//用于算出每一项
	for (i = 0; i < n; i++)//前n项,算n次
	{
		k = k * 10 + a;//利用规律算出每一项
		sum += k;//每一项相加
	}

	//输出结果:
	printf("%d\n", sum);

	return 0;
}

                   

测试图片:

                     


                      

4. 喝汽水问题

题目:

喝汽水,1瓶汽水1元2个空瓶可以换一瓶汽水,给20元,可以喝多少汽水(编程实现)

            

第一种方法 -- 实现代码:

//喝汽水问题
//喝汽水,1瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,可以多少汽水(编程实现)。
#include <stdio.h>
int main()
{
	int money = 0; //空瓶数
	int total = 0; //喝的全部瓶数
	int empty = 0; //空瓶数
	//输入钱数:
	scanf("%d", &money);

	total += money;//一开始,有多少钱就有多少瓶
	empty += money;//钱换了多少瓶就有多少空瓶

	//进行空瓶兑换:
	while (empty >= 2)//空瓶大于等于2瓶就进行兑换
	{
		total += empty / 2;//把兑换后的瓶数加到总瓶数中

		empty = empty / 2 + empty % 2;
		//empty / 2:换了多少瓶就又有多少个空瓶,
		//empty % 2:再加上可能没到2瓶不够换的1瓶
		//这两部分加起来才是总空瓶数

		//之后再判断需不需要再循环
	}

	printf("%d", total);

	return 0;
}

            

第一种方法 -- 测试图片:

                    

                   

第二种方法 -- 实现代码:

//喝汽水问题
//喝汽水,1瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,可以多少汽水(编程实现)。
#include <stdio.h>
int main()
{
	int money = 0; //空瓶数
	int total = 0; //喝的全部瓶数
	int empty = 0; //空瓶数
	//输入钱数:
	scanf("%d", &money);

	total += money;//一开始,有多少钱就有多少瓶
	empty += money;//钱换了多少瓶就有多少空瓶

	//利用方法一中发现的规律:
	if (money > 0)
		//防止0元计算出负一瓶的情况
	{
		total = 2 * money - 1;
		//使用规律进行计算
	}

	printf("%d", total);

	return 0;
}

                        

第二种方法 -- 测试图片:

                     


                      

5. 调整数组使奇数全部都位于偶数前面

题目:

输入一个整数数组实现一个函数

调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分

所有偶数位于数组的后半部分

(奇数在数组前面,偶数在数组后面)

                  

实现代码:

//调整数组使奇数全部都位于偶数前面:
//输入一个整数数组,实现一个函数,
//来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,
//所有偶数位于数组的后半部分。
#include <stdio.h>
int main()
{
	//思路:设置 left 和 right ,
	//1.left 从左往右 找偶数
	//2.right 从右往左 找奇数
	//3.left < right:找到就进行调换
	int arr[] = { 1,2,3,4,5,6,7,8,9 };
	int sz = sizeof(arr) / sizeof(arr[0]);

	//给出两个下标:
	int left = 0; //左下标
	int right = sz - 1; //右下标
	
	while (left < right)//多次调换
	{
		//1.
		//从左往右找偶数:
		while ((left < right) && arr[left] % 2 == 1)
		{
			//找到奇数就跳过:left++,但不能跳过right,防止越界
			left++;
		}

		//2.
		//从右往左找奇数:
		while ((left < right) && arr[right] % 2 == 0)
		{
			//找到偶数就跳过:right--,但不能跳过left,防止越界
			right--;
		}

		//3.
		//到这说明left找到了偶数,right找到了奇数,开始进行调换
		if (left < right)
		{
			//进行调换:
			int tmp = arr[left];
			arr[left] = arr[right];
			arr[right] = tmp;
			//调换完后跳过这对值:
			left++;
			right--;
		}
	}
	
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}

	return 0;
}

                 

测试图片:

                     


                      

6. 打印用 * 组成的X形图案

题目:

多组输入一个整数(2~20),表示输出的行数,也表示组成“X”的反斜线和正斜线的长度

              

实现代码:

//打印用 * 组成的X形图案:
//多组输入一个整数(2~20),表示输出的行数,也表示组成“X”的反斜线和正斜线的长度。
#include <stdio.h>
int main()
{
	//思路:实际打印的是 n*n 图案
	//只不过是当 行等于列(正斜线)、行+列=行数-1(反斜线)打印 * 号 

	int n = 0;//输出的行数、正斜线、反斜线 的长度
	
	//多组输入:
	while (scanf("%d", &n) == 1)
	{
		int i = 0; //行
		int j = 0; //列
		for (i = 0; i < n; i++)//循环打印行
		{
			for (j = 0; j < n; j++)//循环打印列 
			{
				if (i == j || (i+j == n-1))
					//i == j:x图形的正斜线
					//i+j == n-1:x图形的反斜线
				{
					printf("*");//打印 * 号
				}
				else
				{
					printf(" ");//打印空格
				}
			}
			//换行
			printf("\n");
		}
	}

	return 0;
}

              

测试图片:

                     


                      

7. 打印用 * 组成的带空格直角三角形图案

题目:

多组输入一个整数(2~20),表示直角三角形直角边的长度,即 * 的数量,也表示输出行数

            

实现代码:

//打印用“*”组成的带空格直角三角形图案
//多组输入,一个整数(2~20),表示直角三角形直角边的长度,即“*”的数量,也表示输出行数。
#include <stdio.h>
int main()
{
	int n = 0;//直角三角形直角边的长度、“*”的数量、输出行数

	//多组输入:
	while (scanf("%d", &n) == 1)
	{
		int i = 0; //行
		int j = 0; //列
		for (i = 0; i < n; i++)//循环打印行
		{
			for (j = 0; j < n; j++)//循环打印列 
			{
				if (i+j < n-1)
					//找到规律:行数+列数 的部分 全是空格
				{
					printf("  ");
					//打印空格,因为要隔一个空格,所以打印两个空格
				}
				else
				{
					printf("* ");
					//打印 * 号,因为要隔一个空格,所以*号后多加一个空格
				}
			}
			//换行
			printf("\n");
		}
	}

	return 0;
}

            

实现图片:

                     


                      

8. 猜名次

题目:

5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果:

            

A选手说:B第二,我第三;

B选手说:我第二,E第四;

C选手说:我第一,D第二;

D选手说:C最后,我第三;

E选手说:我第四,A第一;

比赛结束后,每位选手都说对了一半,请编程确定比赛的名次

            

实现代码:

//猜名次
#include <stdio.h>
int main()
{
	//思路:对用1表示,错用0表示,两个只有一个对
	//,那么有 (一个 + 另一个 = 1),只有一个为真,即1,另一个为假,即0
	int A = 0;
	int B = 0;
	int C = 0;
	int D = 0;
	int E = 0;

	//实现:
	for (A = 1; A <= 5; A++)//A的所有可能性(5个名次)
	{
		for (B = 1; B <= 5; B++)//B的所有可能性(5个名次)
		{
			for (C= 1; C <= 5; C++)//C的所有可能性(5个名次)
			{
				for (D = 1; D <= 5; D++)//D的所有可能性(5个名次)
				{
					for (E = 1; E <= 5; E++)//E的所有可能性(5个名次)
					{
						//组合排列了所有情况,把符合所有人说的情况全列出来
						if (((B == 2) + (A == 3) == 1) &&
							((B == 2) + (E == 4) == 1) &&
							((C == 1) + (D == 2) == 1) &&
							((C == 5) + (D == 3) == 1) &&
							((E == 4) + (A == 1) == 1))
						{
							if (A * B * C * D * E == 120)//5个名次各只出现一次
							{
								printf("A=%d B=%d C=%d D=%d E=%d\n", A, B, C, D, E);
							}
						}
					}
				}
			}
		}
	}

	return 0;
}

            

实现图片:

                     


                      

9. 猜凶手

题目:

日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个。

以下为4个嫌疑犯的供词:

A说:不是我。

B说:是C。

C说:是D。

D说:C在胡说

已知3个人说了真话1个人说的是假话

现在请根据这些信息,写一个程序来确定到底谁是凶手

            

实现代码:

//猜凶手
#include <stdio.h>
int main()
{
	//思路:依次假设每人是凶手进行判断,
	//看4人说的话是不是1假3真,是则证明假设的该人就是凶手
	char killer = 0;//凶手

	for (killer = 'a'; killer < 'd'; killer++)
	//因为 a b c d 的ASCII码值是连着的,所以a+1==b,
	//以此类推,依次假定每个人是凶手,判断情况
	{
		if ((killer != 'a') + (killer == 'c') + (killer == 'd') + (killer != 'd') == 3)
		//把4句话,4个情况列出来,情况1假3真,真为1,假为0,4种情况“相加”==3,符合就是凶手进行打印
		{
			printf("%c\n", killer);
			break;
		}
	}

	return 0;
}

            

实现图片:

                      


                      

10. 杨辉三角

题目:

在屏幕上打印杨辉三角

1

1 1

1 2 1

1 3 3 1

……

           

实现代码:

//杨辉三角
#include <stdio.h>
int main()
{
	//思路:把三角形的前面的空格去掉,变成直角三角形,
	//再看成对应的长方形,使用二维数组进行遍历

	int arr[10][10] = { 0 };
	
	int i = 0;
	for (i = 0; i < 10; i++)//打印二维数组的行
	{
		int j = 0;
		for (j = 0; j <= i; j++)//打印二维数组的列
			//这里判断条件 j<=i 指:只打印出杨辉三角的那一边
		{
			if (i==j || j==0)//填上杨辉三角两边的1
			{
				arr[i][j] = 1;
			}
			//第二行开始要计算中间的值:(注:有第0行)
			if (i >= 2 && j >= 1)
			{
				arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];
				//找出两个相加的元素
			}
		}
	}

	for (i = 0; i < 10; i++)
	{
		int j = 0;
		for (j = 0; j <= i; j++)//只需要打印杨辉三角那边的值
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}

	return 0;
}

            

实现图片:

  • 17
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高高的胖子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值