头图

矩阵算法经典例题:旅客国籍判断问题的判断

瞿小凯

原题目:
在一个旅馆中住着6个不同国籍的人,他们分别来自美国、德国、英国、法国、俄罗斯和意大利这几个国家。他们的名字分别叫A、B、C、D、E和F,要说明的是名字的顺序与前面提到的国籍不一定是相互对应的。现在已知:

A和美国人是医生。
E和俄罗斯人是教师。
C和德国人是技师。
B和F曾经当过兵,而德国人从未参过军。
法国人比A年龄大,意大利人比C年龄大。
B同美国人下周要去西安旅行,而C同法国人下周要去杭州度假。

现要求根据上述已知条件,编程求出A、B、C、D、E和F各是哪国人。

初看题目,是不是感觉到信息有点多,有很多的字母,也有很多的身份信息,甚至还有年龄大小的比较,需要我们判断的数量也比较多

不过好在题目中的第一句话提到"旅馆里的每个人都是不同国籍”,那么我们可以根据已知信息,排除某些干扰内容,比如年龄,度假,职业,我们只看其中的国籍,可以得出几个结论:

  A不是美国人
  E不是俄罗斯人
  C不是德国人
  B和F不是德国人
  A不是法国人,c不是意大利人
  B不是美国人,c不是法国人

有了这样的例举,我们的题目是不是清晰了很多,不过问题又来了,比如我们的A,不是美国人,不是法国人,那他剩余国家还有4个,他是哪个,我们该怎么判断。

所以,我这时候用到的矩阵法,估算每一个人的国籍概率。
首先,我打开excel,在里面把我刚刚清洗过滤后的信息放进去(这里我以横轴为国家,纵轴为人)
图片.png

里面的空格填入概率,然后做排除法,我们用0表示非的情况,填入后如下:
图片.png

有了表格,每个的横纵坐标就可以很好的表示,如果我们用算法表示其中某一个的位置的情况,比如第一行第一列,我们可以表示为
a[1][1]=0

所以,我们的完整代码为:

#include <stdio.h>
int main()
{
    const char* m[7] = { " ","美国","英国","法国","德国","意大利","俄罗斯" };  /*国名*/
    int a[7][7], i, j, t, e, x, y;
    for (i = 0; i < 7; i++)  /*初始化条件矩阵*/
        for (j = 0; j < 7; j++)  /*行为人,列为国家,元素的值表示某人是该国人*/
            a[i][j] = j;
    for (i = 1; i < 7; i++)  /*条件矩阵每一列的第0号元素作为该列数据处理的标记*/
        a[0][i] = 1;  /*标记该列尚未处理*/
    a[1][1] = a[2][1] = a[3][1] = a[5][1] = 0;  /*输入条件矩阵中的各种条件*/
    a[1][3] = a[2][3] = a[3][3] = 0;  /*0表示不是该国的人*/
    a[1][4] = a[2][4] = a[3][4] = a[5][4] = a[6][4] = 0;
    a[3][5] = 0;
    a[1][6] = a[3][6] = a[5][6] = 0;
    while (a[0][1] + a[0][2] + a[0][3] + a[0][4] + a[0][5] + a[0][6] > 0)
    {  /*当所有六列均处理完毕后退出循环*/
        for (i = 1; i < 7; i++)  /*i:列坐标*/
            if (a[0][i]) /*若该列尚未处理,则进行处理*/
            {
                for (e = 0, j = 1; j < 7; j++)  /*j:行坐标 e:该列中非0元素计数器*/
                    if (a[j][i])
                    {  /*统计每列中的非0元素个数*/
                        x = j;  /*x变量保存行坐标*/
                        y = i;  /*y变量保存列坐标*/
                        e++;
                    }
                if (e == 1)  /*若该列只有一个元素为非零,则进行消去操作*/
                {
                    for (t = 1; t < 7; t++)
                        if (t != i)
                            a[x][t] = 0;  /*将非零元素所在的行的其它元素置0*/
                    a[0][y] = 0;  /*设置该列已处理完毕的标记*/
                }
            }
    }
    printf("矩阵最终状态为:\n");
    for (i = 0; i < 7; i++)  /*初始化条件矩阵*/
    {
        for (j = 0; j < 7; j++)  /*行为人,列为国家,元素的值表示某人是该国人*/
            printf("%d ", a[i][j]);
        printf("\n");
    }
    printf("\n");
    printf("推断结果为:\n");
    for (i = 1; i < 7; i++)  /*输出推理结果*/
    {
        printf("%c来自", 'A' - 1 + i);
        for (j = 1; j < 7; j++)
            if (a[i][j] != 0)
            {
                printf("%s。\n", m[a[i][j]]);
                break;
            }
    }
    return 0;
}

输出结果为:
图片.png

即求解完毕

阅读 235

我是一个独立思考,喜欢纯粹的人,文科和专科是我曾经的身份牌,技术是我一直的理想。

69 声望
3 粉丝
0 条评论

我是一个独立思考,喜欢纯粹的人,文科和专科是我曾经的身份牌,技术是我一直的理想。

69 声望
3 粉丝
文章目录
宣传栏