Cao Yi

哪个赛车最好

返回目录

按:这个问题来源于网络,算是个经典问题了。

【题目】

四名专家对四款赛车进行了评论:

事实上只有一款赛车最佳,且只有一名专家的评论是正确的。

请找出最佳赛车。

【一般分析】

以上的四句评论可以简化为:

A = 2
B = 4
C = !3
D = !B = !4

上面的数字表示该编号的赛车为最好的意思,没有数量上的含义。

由此可列真值表如下:

  if 1 best if 2 best if 3 best if 4 best
A (best: 2) F T F F
B (best: 4) F F F T
C (best: not 3) T T F T
D (best: not 4) T T T F
count(T) 2 3 1 2

由上表,count(T) == 1时,为合乎条件的解:3号车最好,D说的对的。

【程序表达】

以上的分析过程如何由程序语言表达?

从上面的表中,可以看出能按这么个步骤来实现程序:

循环每个跑车为最好的情况

在每个循环里计算count(T)的值,如果count(T)==1,即得解

(上面似乎应该用程序顺序图来表示,可惜忘了怎么画)

每个车都有两个可能:最好,和不是最好。可以通过多重循环来完成各车不同情况的组合,然后判断每个组合是否符合条件,Java 代码如下:

int[] first = { 0, 1 };// 1号车, 0表示不是最好,1表示为最好
int[] second = { 0, 1 };// 2号车,
int[] third = { 0, 1 };// 3号车,
int[] forth = { 0, 1 };// 4号车
int count = 0; // 所有人说对话的总数
for (int i : first) {
    for (int j : second) {
        for (int k : third) {
            for (int m : forth) {
                if (i + j + k + m == 1) {//只有一个车是最好的
                    count = 0;
                    count += ((j == 1) ? 1 : 0);// 2号赛车是最好的
                    count += ((m == 1) ? 1 : 0);// 4号赛车是最好的
                    count += ((k != 1) ? 1 : 0);// 3号赛车不是最好的
                    count += ((m != 1) ? 1 : 0);// 4号赛车不是最好的
                    if (count == 1) {//只有一个人说的对的
                        System.out.println("1号车:" + ((i == 1) ? "最好" : "不是最好"));
                        System.out.println("2号车:" + ((j == 1) ? "最好" : "不是最好"));
                        System.out.println("3号车:" + ((k == 1) ? "最好" : "不是最好"));
                        System.out.println("4号车:" + ((m == 1) ? "最好" : "不是最好"));
                    }
                }
            }
        }
    }
}

注意:多重循环中,不要使用 continebreak,更不要和标签结合使用,我之前在第一重循环外加了个标签,从最里层的循环体中跳出,出现莫名其妙的结果,这里不多表。完整可运行的代码在这里

以上的代码很直观,但多重循环看得真是愁杀人,其实考虑到只有一个车是最好的,将车的编号用来循环一次,代入到各人说的话中可以得到如下简化的 Java 代码:

for (int i = 1; i <= 4; i++) {
    int count = 0; // 所有人说对话的总数
    count += ((i == 2) ? 1 : 0);// 2号赛车是最好的
    count += ((i == 4) ? 1 : 0);// 4号赛车是最好的
    count += ((i != 3) ? 1 : 0);// 3号赛车不是最好的
    count += ((i != 4) ? 1 : 0);// 4号赛车不是最好的
    if (count == 1) {// 只有一个人说的对的
        System.out.println(i + "号车是最好的");
        if (i == 2) {
            System.out.println("A说的对");
        }
        if (i == 4) {
            System.out.println("B说的对");
        }
        if (i != 3) {
            System.out.println("C说的对");
        }
        if (i != 4) {
            System.out.println("D说的对");
        }
    }
}

完整的可执行代码在这里

如果用 C 语言,利用它用整型1表示布尔值 true 的特性,则可以得到更为简单的代码(参这里(by Kenvisa, zhidao.baidu.com)):

int m; // 赛车的编号
for (m = 1; m < 5; m++)
{
    if (!(m - 2) + !(m - 4) + !!(m - 3) + !!(m - 4) == 1)
    {
        printf("第%d赛车是最好的", m);
    }
}

完整的可执行代码在这里

    int m; // 赛车的编号
    for (m = 1; m < 5; m++)
    {
        if (((m == 2) + (m == 4) + (m != 3) + (m != 4)) == 1)
        {
            printf("第%d赛车是最好的", m);
        }
    }

完整的可执行代码在这里


本文是从Google Sites的旧站迁移过来的。