用C语言解决推理小问题+打印杨辉三角

本节所用基础:
分支和循环语句
二维数组

用三个简单的推理题打开C语言推理的思路


问题1

5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果
A选手说:B第二,我第三;
B选手说:我第二,E第四;
C选手说:我第一,D第二;
D选手说:C最后,我第三;
E选手说:我第四,A第一;
比赛结束后,每位选手都说对了一半,请编程确定比赛的结果;


❀思路分析

1.将每位选手的每种可能获得名次的情况都遍历一遍。

即假设A的名次有五种可能,第一名到第五名,
(将选手的名次赋给选手同名的变量a。)
B的名次有五种可能…

2.在每种的可能情况下,结合现实筛选有效项。
(1)每个名次只能有一个人,每个人只能有一个名次。

即第五名不可能同时为A和B和…
A不可能既是第一名又是第五名…
即五位选手的名次只能有 第一、第二、第三、第四、第五。每种名次出现一次的情况
实现操作((A+B+C+D+F)==(1+2+3+4+5))&&((A*B*C*D*F) ==(1*2*3*4*5))

(2)判断每位选手说的话只有一半对。

例如:A说“B第二,我第三”只有一半对
实现操作((b == 2)+(a == 3))== 1
判断两个语句的真假值,
如果对一半,两句一真一假,1+0=1.
如果全队,两句全真,1+1 = 2.
如果全错,两句全假。0+0=0.

#include<stdio.h>
int main()
{
	int a, b, c, d, e; //a,b,c,d,e分别代表选手A,B,C,D,E。用for循环来全排列全部选手的全部名次可能
	for (a = 1; a <= 5; a++) //A选手的名次可能为1~5
	{ 
		for (b = 1; b <= 5; b++) //B选手的名次可能为1~5
		{
			for (c = 1; c <= 5; c++) //C选手的名次可能为1~5
			{
				for (d = 1; d <= 5; d++) //D选手的名次可能为1~5
				{
					for (e = 1; e <= 5; e++) //E选手的名次可能为1~5
					{
						if (((a*b*c*d*e == 120) && (a + b + c + d + e == 15)) && (((a == 3) +(b == 2)) == 1) && ((((b == 2) + (e == 4)) == 1) && (((c == 1) + (d == 2)) == 1) && (((c == 5) + (d == 3)) == 1) && (((e == 4) + (a == 1)) == 1)))
						{
							printf("A的名次为:%d\nB的名次为:%d\nC的名次为:%d\nD的名次为:%d\nE的名次为:%d \n", a, b, c, d, e);
						}	 
					} 
			 	}
			}
		}
	}
	system("pause");
	return 0;
}

结果如图

问题2

某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯//的一个。以下为4个嫌疑犯的供词。
A说:不是我。
B说:是C。
C说:是D。
D说:C在胡说
已知3个人说了真话,1个人说的是假话。
现在请根据这些信息,写一个程序来确定到底谁是凶手。


❀思路分析

1.让杀手变量从A到D遍历一遍

在每种可能情况下判断是否符合条件

2.判断四句话的真假

实现操作((killer != 'A') + (killer == 'C') + (killer == 'D') + (killer != 'D')) == 3
四条语句都有真假值,只有三真一假时,语句相加结果为3.

#include<stdio.h>
int main()
{
	char killer; //定义这个杀手变量
	for (killer = 'A'; killer <= 'D'; killer++) //循环,使杀手这个变量从A到D依次赋值过
	{
		if (((killer != 'A') + (killer == 'C') + (killer == 'D') + (killer != 'D')) == 3) //满足条件三真一假时成立
			printf("凶手就是\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n猜到了吗?\n\n\n\n\n\n\n\n%c干掉他!\n", killer);
	}
system("pause");
return 0;
}

这里写图片描述

问题3

在屏幕上打印杨辉三角
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
规律,每一位为上一行该列+上一行该列的前一列


❀思路分析

1.先打印如题的直角杨辉三角,打印好后调整形状。
(1)定义二维数组,存放杨辉三角中的数值

观察杨辉三角,发现第一列(j == 0)和对角线上(i == j)的数字都为1,(用i表示行序号,j表示列序号)
且杨辉三角的数字只分布在数组的左下角。
实现操作if ((i == j)||(j == 0)) { yang[i][j] = 1; //先打印数组的第一列和对角线一列,因为他们全为1 }

(2)每一位为上一行该列+上一行该列的前一列,如图所示

这里写图片描述
实现操作yang[i][j] = yang[i - 1][j] + yang[i - 1][j - 1];

2.调整空格,使直角三角形打印出金字塔型
(1)观察每行第一个元素前的空格,依次减小

实现操作printf("%*d", 20- 2*i, yang[i][0]);
20-2i为随显示修改的结果,并非固定表达,注:表达式中与20-2*i对应

(2)随后输出的数打够空格,调整位置即可。

实现操作printf(" %d ", yang[i][j]);

#include <stdio.h>
#define N 10 //宏定义一个常量,可改变数字以改变杨辉三角显示的行数
int main()
{
    //赋值
	int i = 0, j =0;int yang[N][N] = { 0 };
	for (i = 0; i < N; i++)
	{
		for (j = 0; j < N; j++)
		{
			if ((i == j)||(j == 0))
			{
				yang[i][j] = 1; //先赋值数组的第一列和对角线一列,因为他们全为1
			}
			else
			{
				yang[i][j] = yang[i - 1][j] + yang[i - 1][j - 1]; /*赋值,每一个元素的值为 他对应列上一行的元素+他对应列的前一列的上一行的元素。例如题目所显示的直角形杨辉三角*/
			}
		}
	}
	//打印
	for (i = 0; i < N; i++)
	{ 
		printf("%*d", 20- 2*i, yang[i][0]); /*打印杨辉三角每一行的第一个元素,前需空格随行数依次减小,20-2*i为随显示修改的结果,并非固定表达,注:表达式中*与20-2*i对应*/
		for (j = 1; j <= i; j++) 
		{
			printf(" %d ", yang[i][j]); //打印该行其余数字,只需固定空格即可
		}
		printf("\n");
	}
	system("pause");
	return 0;
}

结果如下
❤关于“%*d”

printf("%*d", 20- 2*i, yang[i][0]);
其中表示%*d中的*,是一个标志符号,用来表示跳过它相应的数据。
例如printf("%*d", 4, 6);
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值