C语言编程解趣题系列——找凶手和比赛名次

举报
未见花闻 发表于 2022/04/30 00:14:46 2022/04/30
【摘要】 C语言编程解趣题系列——找凶手和比赛名次

⭐️前面的话⭐️

这篇文章博主将分享两个有趣的问题找凶手和比赛名次,让学习C语言不枯燥。

📒博客主页:未见花闻的博客主页
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
📌本文由未见花闻原创!
📆华为云首发时间:🌴2022年4月30日🌴
✉️坚持和努力一定能换来诗与远方!
💭参考书籍:📚《C语言程序设计》
💬参考在线编程网站:🌐牛客网🌐力扣
博主的码云gitee,平常博主写的程序代码都在里面。
博主的github,平常博主写的程序代码都在里面。
🍭作者水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!

:closed_lock_with_key:问题1:找凶手

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

:bulb:解题思路

首先根据我们人类的思维可以确定一共有4种情况将这些情况列成一个表(其中1代表真,0代表假):

A B C D 推断
0 1 1 1 C,D矛盾
1 0 1 1 C,D矛盾
1 1 0 1 C是凶手
1 1 1 0 B,C矛盾

根据推理:
B,C中必有一个说谎;
C,D中必有一个说谎;
A,D说的一定是真话。
所以推断出C是凶手。

人类可以通过像这样的推理得到谁是凶手,但是计算机不行,它没有人类的思维,所以想要使用编程解决这道题,必须从计算机的角度出发,以计算机的思维解决。
通过题目可知四句话三真一假,所以我们可以通过设立四个判断语句,满足四个判断语句结果之和为3,这就模拟了三真一假。
对于判断语句,A,B,C,D四个人的话翻译一下可以得到:
A:murderer != 'A'
B:murderer == 'C'
C:murderer == 'D'
D:murderer != 'D'
我们可以假设一个凶手,比如从A开始,然后进行四个条件判断并将其结果加起来,如果满足判断结果之和为3,则A就是凶手。

:key:编程代码与运行结果
编程代码:

#include <stdio.h>
int main()
{
	int i = 0;
	char murderer = 'A';
	for (i = 0; i < 4; i++)
	{
		murderer = 'A' + i;//假设凶手是A
		int sum = 0;
		sum = (murderer != 'A') + (murderer == 'C') + (murderer == 'D') + (murderer != 'D');//它们四个人三个人说了真话
		if (sum == 3)
		{
			printf("%c是凶手。\n", murderer);//C是凶手
			break;
		}
	}
	return 0;
}

运行结果:

C是凶手。

D:\gtee\C-learning-code-and-project\猜凶手\Debug\猜凶手.exe (进程 29596)已退出,代码为 0。
按任意键关闭此窗口. . .

与我们想的一致,完成!

:closed_lock_with_key:问题2:比赛名次

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

:bulb:解题思路

用计算机的思维,首先将5位运动员讲的话以说对一半的形式翻译成5个判断语句,这里所谓的“说对一半”,就是5位运动员中一句话为真,一句话为假。翻译成判断语句如下:
A = (((b == 2) && (a == 3)) == 0) && (((b == 2) || (a == 3)) == 1);
B = (((b == 2) && (e == 4)) == 0) && (((b == 2) || (e == 4)) == 1);
C = (((c == 1) && (d == 2)) == 0) && (((c == 1) || (d == 2)) == 1);
D = (((c == 5) && (d == 3)) == 0) && (((c == 5) || (d == 3)) == 1);
E = (((e == 4) && (a == 1)) == 0) && (((e == 4) || (a == 1)) == 1);
满足A+B+C+D+E==5A*B*C*D*E=1就能模拟5位运动员说的话了。

A = (b == 2) + (a == 3);
B = (b == 2) + (e == 4);
C = (c == 1) + (d == 2);
D = (c == 5) + (d == 3);
E = (e == 4) + (a == 1);
满足A*B*C*D*E=1就能模拟5位运动员说的话了。
然后就是将所有的可能情况列出来,去通过这5个判断,如果满足A*B*C*D*E=1就能得到比赛的名次。
对于怎么得出所有的比赛名次情况,有两种方法:
方法1:使用5个嵌套的循环将所有1 2 3 4 5名次组合数得出来,但是名次是不能出现重复的,那我们就将得到的组合数全部乘起来,如果结果等于1*2*3*4*5=120,就满足得到的组合数每个都不相同,这样名次就不会重复了。
方法2:使用随机数,得到5个范围为1~5的数,同理为了避免名次重复,通过判断5个数的乘积结果是否为120,来筛选没有重复数字的组合。
:key:编程代码与运行结果
方法1编程代码:

#include <stdio.h>

int main()
{
	int a = 0;
	int b = 0;
	int c = 0;
	int d = 0;
	int e = 0;
	int A = 0;
	int B = 0;
	int C = 0;
	int D = 0;
	int E = 0;
	int test = 0;

	for (a = 1; a <= 5; a++)
	{
		for (b = 1; b <= 5; b++)
		{
			for (c = 1; c <= 5; c++)
			{
				for (d = 1; d <= 5; d++)
				{
					for (e = 1; e <= 5; e++)
					{
						if (a * b * c * d * e == 120)//生成五位选手所有排名可能
						{
							A = (((b == 2) && (a == 3)) == 0) && (((b == 2) || (a == 3)) == 1);
							B = (((b == 2) && (e == 4)) == 0) && (((b == 2) || (e == 4)) == 1);
							C = (((c == 1) && (d == 2)) == 0) && (((c == 1) || (d == 2)) == 1);
							D = (((c == 5) && (d == 3)) == 0) && (((c == 5) || (d == 3)) == 1);
							E = (((e == 4) && (a == 1)) == 0) && (((e == 4) || (a == 1)) == 1);
							//A = (b == 2) + (a == 3);
							//B = (b == 2) + (e == 4);
							//C = (c == 1) + (d == 2);
							//D = (c == 5) + (d == 3);
							//E = (e == 4) + (a == 1);
							//test = A + B + C + D + E;//满足五位选手说的话半句真半句假,后面判断条件要要改为test == 5;
							test = A * B * C * D * E;//满足五位选手说的话为半真
							if (a * b * c * d * e == 120)
							{
								if (test == 1)
								{
									printf("A->%d B->%d C->%d D->%d E->%d\n", a, b, c, d, e);
									break;
								}
							}
						}
					}
				}
			}
		}
	}
	return 0;
}

方法1运行结果:

A->3 B->1 C->5 D->2 E->4

D:\gtee\C-learning-code-and-project\test_809\Debug\test_809.exe (进程 20136)已退出,代码为 0。
按任意键关闭此窗口. . .

方法2编程代码:

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main()
{
	int a = 0;
	int b = 0;
	int c = 0;
	int d = 0;
	int e = 0;
	int A = 0;
	int B = 0;
	int C = 0;
	int D = 0;
	int E = 0;
	int test = 0;
	srand((unsigned int)time(NULL));
	while(1)
	{
		a = rand() % 5 + 1;
		b = rand() % 5 + 1;
		c = rand() % 5 + 1;
		d = rand() % 5 + 1;
		e = rand() % 5 + 1;//利用随机数生成五位选手排名可能情况
		
		if (a * b * c * d * e == 120)
		{
			//A = (((b == 2) && (a == 3)) == 0) && (((b == 2) || (a == 3)) == 1);
			//B = (((b == 2) && (e == 4)) == 0) && (((b == 2) || (e == 4)) == 1);
			//C = (((c == 1) && (d == 2)) == 0) && (((c == 1) || (d == 2)) == 1);
			//D = (((c == 5) && (d == 3)) == 0) && (((c == 5) || (d == 3)) == 1);
			//E = (((e == 4) && (a == 1)) == 0) && (((e == 4) || (a == 1)) == 1);
			A = (b == 2) + (a == 3);
			B = (b == 2) + (e == 4);
			C = (c == 1) + (d == 2);
			D = (c == 5) + (d == 3);
			E = (e == 4) + (a == 1);
			test = A * B * C * D * E;//满足五位选手说的话为半真
			if (test == 1)
			{
				printf("A->%d B->%d C->%d D->%d E->%d\n", a, b, c, d, e);//如果得出排名打印并退出循环
				break;
			}
		}
	}
	return 0;
}

方法2运行结果:

A->3 B->1 C->5 D->2 E->4

D:\gtee\C-learning-code-and-project\test_809\Debug\test_809.exe (进程 31128)已退出,代码为 0。
按任意键关闭此窗口. . .

两种方法结果一致,都得到了五位比赛选手的排名。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。