趣味数学编程题解之谁是真凶

IT商界

  题目:谁是真凶

  上小学时的一位好朋友在派出所工作,上岗考试中有这样一道分析题请我来和他共同分享一下,题目是这样的:

  某地发生一起特大盗窃案,与本案有关的犯罪嫌疑人有6人,他们分别是A、B、C、D、E、F,现已查明有下面6条线索:

  1.A、B中至少有一人作案;

  2.A、D两人不可能是同案犯;

  3.A、E、F中有两人参与作案;

  4.B、C或同时作案,或同时与本案无关;

  5.C、D中有且只有一人作案;

  6.如果D没有参与作案,则E也不可能参与作案。

  要求从中找出真凶。

  编程思路

  首先,计算机怎么找真凶呢?主要可分两步走:一、布下天网,按人头谁也不能轻易放过;二、6个条件必须全部符合,只要有一个不符合,那就只能放人,不能冤枉好人。

  为了公平公正起见,需要对所有的可能的凶手排查一遍,怎么排查呢?因为对于ABCDEF这6个字母我们不好从中找规律,可通过一个数组来放他们,因为6个人还有自身的属性,可能是凶手,可能不是,我们通过一个二维数组来实现上面的设想,a(1,1))、a(1,2))...... a(1,6))来表示ABCDEF这6个人,用a(2,1))、a(2,2))...... a(2,6))来表示ABCDEF这6个人的状态,如果为t则表示为凶手,为f则表示不是凶手。有了上面的假设,我们就可放心大胆地找其中的规律了。

  下面的代码用来实现4个凶手和两个凶手的情况。

  For k = 1 To 5

  For j = k + 1 To 6

  '4个凶手情况

  For i = 1 To 6

  '初始化嫌疑人数组

  a(2,i)) = "t"

  Next i

  a(2,k)) = "f"

  a(2,j)) = "f"

  Call Cation

  '两个凶手情况

  For i = 1 To 6

  ' '初始化嫌疑人数组

  a(2, i)) = "f"

  Next i

  a(2, k)) = "t"

  a(2, j)) = "t"

  Call Cation

  Next j

  Next k

  第二步怎么实现呢?

  其中6个条件我们通过定义一子程序Cation()来实现。6个条件的实现和第一步有着紧密的联系,A的情况放在a(2,1))中,是好人还是坏人就看这里面放的是什么数值了,如果是t,说明是,如果是f,说明不是。

  再通过定义一个标志变量来记录下比较的信息。如果和条件相符,则将标志变量加1,否则不加。通过标志变量的值我们就可判定一组方案是不是符合6个条件。如果成立,这一组就是罪犯,只要有一组不符合,那就甭向下找了,说明这一组不是。源程序如下:

  源代码下载地址:http://www.cpcw.com/download/soft/33/33-c13-dm1.txt

  上面的6个条件中,有几个挺别扭的,需要反复思考,有时通过考虑其反面的情况更加容易一些。如条件6,如果D没有作案,则E也不可能作案,反过来考虑更容易理解,即E做案了,D一定作案了,E没有作案,D可能作案,也可能未作案。

  窗体和源程序

  窗体非常简单,用到1个文本框两个按钮。文本框用来放置输出结果,按钮用来判断和退出。下面的源程序只要将上面的Cation())函数首先声明,再加入下面的代码就行了。

  源代码下载地址:http://www.cpcw.com/download/soft/33/33-c13-dm2.txt

  小 结

  (1)一个完整的示例比说多少话都有说服力。

  将程序编完了,调试成功,就是对编程的最好总结。里面用到了数组,有它们的归类,还有不止一个循环,在调试的时候,又在向自己挑战。怎么还不行呢?教科书里的东东是不是在骗人呢?随着程序的完成,一切都不存在了。只要将一个好的事例解决掉,教科书中的枯燥说教就成了生动的代码。

  (2)留心生活中的好素材,不要放过到手的编程题材。

  好的示例是非常难得的,留心生活中我们可能遇到的那些优秀的编程材料。其实那些活生生的程序,正是我们思想。思想者的价值就在于此,这也是编程的巨大魅力所在。