原题目:
在一个旅馆中住着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,在里面把我刚刚清洗过滤后的信息放进去(这里我以横轴为国家,纵轴为人)
里面的空格填入概率,然后做排除法,我们用0表示非的情况,填入后如下:
有了表格,每个的横纵坐标就可以很好的表示,如果我们用算法表示其中某一个的位置的情况,比如第一行第一列,我们可以表示为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;
}
输出结果为:
即求解完毕
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。