五名运动员参加了10米台跳水比赛,预测比赛结果:
A选手说:B第二,我第三;
B选手说:我第二,E第四;
C选手说:我第一,D第二;
D选手说:C最后,我第三;
E选手说:我第四,A第一;
比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。
先看解题:
int main()
{
int a = 0;
int b = 0;
int c = 0;
int d = 0;
int 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++) //(嵌套循环)
{
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) //(对名次的合理性进行判断)
printf("a=%d b=%d c=%d d=%d e=%d", a, b, c, d, e);
}
}
}
}
}
}
return 0;
}
从题中可知:1.总共有五个运动员,也就是说,每位运动员都可能得到1,2,3,4,5名中的任意一名。 2.每名运动员的两句话(就拆成两句吧)中只有一句是真话。
那么,放在编程题中我们便可以将这五名运动员初始化成a,b,c,d,e,用int的形式(红字部分),我思考的过程中被他们讲的话误导,一开始是初始化成char的形式,并且打算将每个运动员的话都罗列出来,后来发现根本不需要(包括也没能力)。
随后,如何规范良好地表示出运动员的名次排序呢?这时候还不能直接进行名次判断,而是将abcde所有可能的名次全部罗列出来,于是嵌套循环登场(蓝字部分)。
嵌套的最后,我们终于可以开始判断了。已知运动员只有一句话是对的,另一句话是错的,而正确的那句话我们并不知道(可以动笔算,但不建议)。于是我们自然而然想到利用判断句。。。然后呢?如何进行判断?貌似有一个“1”能够代表真,“0”能代表假,而这也正好符合题意,一真一假,两个相加正好就是“1”。而如果所有运动员说的话都为“1”的话,那回答就成立了。(判断的过程包含了5的5次方循环)
于是答案就出来啦!赶紧劈里啪啦写上printf(******),运行的答案却是这样的:
a=1 b=2 c=1 d=3 e=1a=1 b=2 c=1 d=3 e=2a=1 b=2 c=1 d=3 e=3a=1 b=2 c=1 d=3 e=5a=1 b=2 c=5 d=2 e=1a=1 b=2 c=5 d=2 e=2a=1 b=2 c=5 d=2 e=3a=1 b=2 c=5 d=2 e=5a=3 b=1 c=1 d=3 e=4a=3 b=1 c=5 d=2 e=4a=3 b=3 c=1 d=3 e=4a=3 b=3 c=5 d=2 e=4a=3 b=4 c=1 d=3 e=4a=3 b=4 c=5 d=2 e=4a=3 b=5 c=1 d=3 e=4a=3 b=5 c=5 d=2 e=4
怎么回事?逻辑明明白白是正确的,问题出在哪里?仔细看看上面的判断,在这里我们仅仅判断了为“1”的所有可能性,这其中当然包含五个运动员“平局”的可能——仔细看看上面的数字,有一些相邻的重复了。毕竟咱们不支持平局,于是便加上“ if (a*b*c*d*e == 120) ”这一条件句,意思是名次刚刚好是1到5名,而从1乘到5正好是120,于是最终答案便到手了。
a=3 b=1 c=5 d=2 e=4