5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果
A选手说:B第一,我第三。
B选手说:我第二,E第四。
C选手说:我第一,D第二。
D选手说:C最后,我第三。
E选手说:我第四,A第一。
比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。
我的解题方法:完全将题转换成C语言,列出所有可能,判断后输出
有点长,清除格式好看点
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<windows.h>
int main()
{
int i[5] = { 0 };//分别对应A~E说的某一句话
int a[5][2][2] = { { 2, 1, 1, 3 }, { 2, 2, 5, 4 }, { 3, 1, 4, 2 }, { 3, 5, 4, 3 }, { 5, 4, 1, 1 } };
//第一维[5]表示A到E说的话,第二维[2]表示说的第一句和第二局话,
//第三维[2]表示每句话的内容,第一个数(1~5)对应(A~E),第二个数表示名次。
for (i[0] = 0; i[0] < 2; i[0]++)
{
for (i[1] = 0; i[1] < 2; i[1]++) //五个for循环列出所有可能出现的情况
{
for (i[2] = 0; i[2] < 2; i[2]++) //例如:i[0]=1表示第(0+1)个人说的第(0+1)句话是正确的
{
for (i[3] = 0; i[3] < 2; i[3]++)
{
for (i[4] = 0; i[4] < 2; i[4]++)
{
int j = 0;
int k = 0;
for (j = 0; j < 5; j++) //这个嵌套for循环用于判断所选出的判断相互不冲突
{
for (k = (j + 1); k < 5; k++)//外层循环表示选出的一个判断,内层表示另一个
{
if ((a[j][i[j]][0] == a[k][i[k]][0]) && (a[j][i[j]][1] != a[k][i[k]][1]))
{ //当同一个人 有不同名次
goto bool; //不符合条件,结束此次判断
}
}
}
for (k = 0; k < 5; k++) //这个两层for循环用于判断未选出的语句是错误的
{ //!i[k]表示第(k+1)个人未选出的语句
for (j = 0; j < 5; j++) //与五个正确语句比较
{ //选出的语句 错误语句
if (((a[j][i[j]][0] == a[k][!i[k]][0]) && (a[j][i[j]][1] != a[k][!i[k]][1])) || //同一个人不同名次或
((a[j][i[j]][0] != a[k][!i[k]][0]) && (a[j][i[j]][1] == a[k][!i[k]][1]))) //人不同名次相同
{
break; //该语句与选出语句冲突,判断下条语句
}
}
if (j == 5) //该语句不与选出的语句冲突,语句为真,有人两个判断都正确
{
goto bool; //结束此次判断
}
}
for (j = 1; j <= 5; j++) //从A到E确定名次
{
for (k = 0; k < 5; k++) //从正确语句中找A到E
{
if (a[k][i[k]][0]==j) //找到就输出
{
printf("%c 是第 %d 名。\n", ('A' + j - 1), a[k][i[k]][1]);
goto bol; //找下一个
}
}
//没找到
for (k = 1; k <= 5; k++) //从第一名开始找空缺的名次
{
if ((a[0][i[0]][1] != k)&&(a[1][i[1]][1] != k)&&
(a[2][i[2]][1] != k)&&(a[3][i[3]][1] != k)&&
(a[4][i[4]][1] != k))//空缺名次必同时不等于所有已有名次
{
printf("%c 是第 %d 名。\n", ('A' + j - 1), k);
goto bol; //找下一个
}
}
bol: continue; //找下一个人
//printf("%c 是第 %d 名。\n", ('A' + a[j][i[j]][0]- 1) , a[j][i[j]][1]);>>之前用于直接输出正确语句
}
bool : continue; //结束一次判断,开始判断下一种可能
}
}
}
}
}
system("pause");
return 0;
}
运行结果
我知道看到这心里坑定艹了,我自己都艹了,这么长还理论上有bug
来看看参考答案
解题方法:定义A~E为变量,赋值名词次,五个for循环给出所有可能,条件判断,
名次从1开始的连续性判断,通过输出
看代码
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<windows.h>
int main()
{
int a = 0, b = 0, c = 0, d = 0, e = 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++)
{
int count = 0;
if (((b == 1) + (a == 3) == 1) &&
((b == 2) + (e == 4) == 1) &&
((c == 1) + (d == 2) == 1) &&
((c == 5) + (d == 3) == 1) &&
((e == 4) + (a == 1) == 1))
{
count |= 1 << (a - 1);
count |= 1 << (b - 1);
count |= 1 << (c - 1);
count |= 1 << (d - 1);
count |= 1 << (e - 1);
while (count % 2 != 0)
{
count /= 2;
}
if (count == 0)
{
printf("A是第%d名\nB是第%d名\nC是第%d名\nD是第%d名\nE是第%d名\n", a, b, c, d, e);
}
}
}
}
}
}
}
system("pause");
return 0;
}
其实我的方法也不是没有优势,改一下问题,参考答案就挂了
问题:编程确定每个人正确的判断并输出
程序去掉排序输出过程即可(这其实是最初的版本)
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<windows.h>
int main()
{
int i[5] = { 0 };//分别对应A~E说的某一句话
int a[5][2][2] = { { 2, 1, 1, 3 }, { 2, 2, 5, 4 }, { 3, 1, 4, 2 }, { 3, 5, 4, 3 }, { 5, 4, 1, 1 } };
//第一维[5]表示A到E说的话,第二维[2]表示说的第一句和第二局话,
//第三维[2]表示每句话的内容,第一个数(1~5)对应(A~E),第二个数表示名次。
for (i[0] = 0; i[0] < 2; i[0]++)
{
for (i[1] = 0; i[1] < 2; i[1]++) //五个for循环列出所有可能出现的情况
{
for (i[2] = 0; i[2] < 2; i[2]++) //例如:i[0]=1表示第(0+1)个人说的第(0+1)句话是正确的
{
for (i[3] = 0; i[3] < 2; i[3]++)
{
for (i[4] = 0; i[4] < 2; i[4]++)
{
int j = 0;
int k = 0;
for (j = 0; j < 5; j++) //这个嵌套for循环用于判断所选出的判断相互不冲突
{
for (k = (j + 1); k < 5; k++)//外层循环表示选出的一个判断,内层表示另一个
{
if ((a[j][i[j]][0] == a[k][i[k]][0]) && (a[j][i[j]][1] != a[k][i[k]][1]))
{ //当同一个人 有不同名次
goto bool; //不符合条件,结束此次判断
}
}
}
for (k = 0; k < 5; k++) //这个两层for循环用于判断未选出的语句是错误的
{ //!i[k]表示第(k+1)个人未选出的语句
for (j = 0; j < 5; j++) //与五个正确语句比较
{ //选出的语句 错误语句
if (((a[j][i[j]][0] == a[k][!i[k]][0]) && (a[j][i[j]][1] != a[k][!i[k]][1])) || //同一个人不同名次或
((a[j][i[j]][0] != a[k][!i[k]][0]) && (a[j][i[j]][1] == a[k][!i[k]][1]))) //人不同名次相同
{
break; //该语句与选出语句冲突,判断下条语句
}
}
if (j == 5) //该语句不与选出的语句冲突,语句为真,有人两个判断都正确
{
goto bool; //结束此次判断
}
}
for (j = 0; j < 5; j++)
{
printf("%c判断%c 是第 %d 名正确。\n", ('A' + j), ('A' + a[j][i[j]][0] - 1), a[j][i[j]][1]);
}
bool : continue; //结束一次判断,开始判断下一种可能
}
}
}
}
}
system("pause");
return 0;
}