“还记得八皇后的解法吗?”
“上个世纪的事情,不记得了。”
“…… 现在回忆一下?”
“开会,回头说。”
“ fuck u ”
“ u shit ”
我有一个C++基友,这么称呼是因为他入行时用的是C++。虽然在游走于腾讯、金山之后,如今已经十八般武艺略懂了,但说起来还是C++的标签最刺眼。
当你有一个C++基友时,QQ里的日常,难免就会碰到上面那种聊天记录了。
八皇后是一个古老的经典问题:如何在一张国际象棋的棋盘上,摆放8个皇后,使其任意两个皇后互相不受攻击。该问题由一位德国国际象棋排局家 Max Bezzel 于 1848年提出。严格来说,那个年代,还没有“德国”这个国家,彼时称作“普鲁士”。
Max Bezzel
1850年,Franz Nauck 给出了第一个解,并将其扩展成了“ n皇后 ”问题,即在一张 n 维棋盘上,如何摆放 n 个皇后,使其两两互不攻击。
历史上,八皇后问题曾惊动过“数学王子”高斯(Gauss),而且正是上面这个 Franz Nauck 写信找高斯请教的。
高斯和八皇后问题
在那天被基友问到时,我并非真的不记得了,而是我压根就没有做过。但我第一次遇见这个问题时,确实是在上个世纪,那是在小学微机教室里,参加市级计算机奥林匹克小学组竞赛的培训课上。
我还记得初次看到这个问题的第一反应——怎么可能摆8个!要知道我初学国际象棋时,经常为了简化局面,早早地就伺机兑掉皇后,因为皇后的威力实在是溢出了我童年的脑袋。一个皇后感觉就可以 hold 住全场了,怎么还可以摆8个互不干扰的呢?这肯定无解。
所以说,童言无忌这个说法,是有必要的。
一晃好多年。如今基友问过来了,我琢磨着是该补上这份作业了。
给老爸拨了个电话——
“喂,爸,家里的国际象棋放哪了?”
“…… 压箱底了吧,得找找。怎么突然问这,你要研究西西里防御?”
“我现在都不走 e4 了,要研究也是后翼弃兵。”
“别特么瞎扯,给你根杆子你就爬啊,快说,有什么屁事?”
“我要研究八皇后问题。”
“讲中文!”
“我有个问题想研究一下,要在国际象棋棋盘上摆放八个皇后,并且互相不受攻击,求摆法。”
“哦,这样啊…… 那你要国际象棋干嘛?”
“我想在国际象棋上试着摆摆啊。”
“国际象棋没有八个皇后,你要国际象棋干嘛?”
“呃…… 那我可以拿八个兵当皇后做试验。”
“那你直接画个棋盘摆八个硬币不是一回事?非要用国际象棋?脱裤子放屁,多此一举!”
“…… ……”
“老子懒得翻箱子跟你找了,你干脆去买四副国际象棋,然后就有八个皇后了。还有事吗?”
“没…… 没了,爸。”
“早点休息,多喝水,别熬夜。天气冷了,注意加衣服……”
“好,好好。”
—— 对方挂断,通话结束。
我默默地打开了淘宝,搜索“国际象棋”,准备买 4 副……
转念一想,还是算了,自己画吧。
转念二想,懒得画了,就在脑子里摆摆看吧。
首先,做点分析工作。虽然还不知道最终的答案长什么样,有多少个,但利用国际象棋的规则,可以知道的是,最终8个皇后的分布必定是每行有且只有1个,每列有且只有1个。因为如果有某一行(或列)空置的话,则必然导致另有一行(或列)存在2个皇后。这显而易见的结果背后,有一个数学概念叫做“抽屉原则”。借助这个“抽屉”,接下来要做的就是一行一行地找出8个位置。当然,按一列一列来做也可以,但在处理图形图像等信息时,优先水平方向似乎更符合人的思维惯性,据说这是因为人的两只眼睛是水平的。(跑题了……)