C语言编程解趣题系列——找凶手和比赛名次
Posted 未见花闻
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言编程解趣题系列——找凶手和比赛名次相关的知识,希望对你有一定的参考价值。
⭐️前面的话⭐️
嗨喽!我要来水文章咯!上一篇文章介绍了C语言库中一些关于字符的函数和深入了解了指针,相信大家都看累了,这篇文章博主将分享两个有趣的问题找凶手和比赛名次,让学习C语言不枯燥。
📒博客主页:未见花闻的博客主页
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
📌本文由未见花闻原创,CSDN首发!
✉️坚持和努力一定能换来诗与远方!
🙏作者水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!
博主的码云gitee,平常博主写的程序代码都在里面。
🔐问题1:找凶手
日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个。
以下为4个嫌疑犯的供词:
A说:不是我。
B说:是C。
C说:是D。
D说:C在胡说。
已知3个人说了真话,1个人说的是假话。
现在请根据这些信息,写一个程序来确定到底谁是凶手。
💡解题思路
首先根据我们人类的思维可以确定一共有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就是凶手。
🔑编程代码与运行结果
编程代码:
#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。
按任意键关闭此窗口. . .
与我们想的一致,完成!
🔐问题2:比赛名次
5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果:
A选手说:B第二,我第三;
B选手说:我第二,E第四;
C选手说:我第一,D第二;
D选手说:C最后,我第三;
E选手说:我第四,A第一;
比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。
💡解题思路
用计算机的思维,首先将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==5
或A*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
,来筛选没有重复数字的组合。
🔑编程代码与运行结果
方法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。
按任意键关闭此窗口. . .
两种方法结果一致,都得到了五位比赛选手的排名。
以上是关于C语言编程解趣题系列——找凶手和比赛名次的主要内容,如果未能解决你的问题,请参考以下文章