这是一个无聊的事情
由于很无聊,就刷牛客网的智力题,遇到一个逻辑推理题,然后我就和这个题杠上了。
请看题:
前提:
1 有五栋五种颜色的房子
2 每一位房子的主人国籍都不同
3 这五个人每人只喝一种饮料,只抽一种牌子的香烟,只养一种宠物
4 没有人有相同的宠物,抽相同牌子的香烟,喝相同的饮料
提示:
1 英国人住在红房子里
2 瑞典人养了一条狗
3 丹麦人喝茶
4 绿房子在白房子左边
5 绿房子主人喝咖啡
6 抽PALL MALL烟的人养了一只鸟
7 黄房子主人抽DUNHILL烟
8 住在中间那间房子的人喝牛奶
9 挪威人住第一间房子
10 抽混合烟的人住在养猫人的旁边
11 养马人住在抽DUNHILL烟的人旁边
12 抽BLUE MASTER烟的人喝啤酒
13 德国人抽PRINCE烟
14 挪威人住在蓝房子旁边
15 抽混合烟的人的邻居喝矿泉水
问题是:谁养鱼???
浪费了我几张纸,累死无数脑细胞,推到吐血,也没推出来,没办法只能使出我的杀手锏(世界上最好的语言)
分析:
5栋房子,5个国籍,5种颜色,5种饮料,5种香烟,5种宠物
暴力破解的第一步就是要把所有的组合列出来吧,也可以大概估算出电脑能不能抗的住
5栋房子就简单的用1,2,3,4,5来顺序排列吧
5种颜色的全组合有多少种呢?初中老师教过,是5的阶乘,也就是5 * 4 * 3 * 2 * 1=120
房子是固定的,剩余有5个变量,也就是一共有120的5次方个组合,也就24883200000组合,我那用了八年的破电脑还是能抗住的。
把所有组合列出来之后,就循环,按照提示进行排除
代码分析
1,生成120种排列组合
function create()
{
$arr = [];
$range = [1, 2, 3, 4, 5];
for ($i = 12345; $i <= 54321; $i++) {
$tmp = str_split($i);
if (count(array_diff($range, $tmp)) == 0) {
$arr[] = $tmp;
}
}
return $arr;
}
这里用的是最简单暴力的方法,就不多解释了
2,怎么来标记这些组合呢,先来组合一下颜色
$arr = create();
foreach ($arr as $k => $v) {
$color['红'] = $v[0];
$color['白'] = $v[1];
$color['绿'] = $v[2];
$color['黄'] = $v[3];
$color['蓝'] = $v[4];
...
}
这个是把颜色作为键名,房子的位置作为键值,生成的$color大概就是这个样子
$color=[
'红'=>2,
'白'=>1,
'绿'=>3,
'黄'=>5,
'蓝'=>4,
];
其他几个变量也用这种来标记
3,逻辑判断,这里是比较关键的一步,由于用排除法来判断,所以条件都要取返,不符合条件的就continue,换下一种组合
1,英国人住在红房子里
if ($county['英国'] != $color['红']) {
continue;
}
如果英国人房子的位置和红色房子的位置不一样,就排除,跳过去
4,绿房子在白房子左边
if ($color['白'] - $color['绿'] != 1) {
continue;
}
房子从左往右排的,绿的在白的左边,也就是绿的位置比白的位置小1
8,住在中间那间房子的人喝牛奶
if ($drink['牛奶'] != 3) {
continue;
}
这就比较简单了,中间的房子位置编号是3,所以喝牛奶的房子位置必须是3
10,抽混合烟的人住在养猫人的旁边
旁边的话要么是位置大1,要么是位置小1,但肯定位置差的绝对值是1
if (abs($smoke['混合'] - $pet['猫']) != 1) {//10
continue;
}
抽混合烟的人与养猫人的位置相差1
大概就是这几种判断了
到这里思路应该就清晰了,剩下的只是敲键盘了,代码如下:
/**
* 生成排列组合
*/
function create()
{
$arr = [];
$range = [1, 2, 3, 4, 5];
for ($i = 12345; $i <= 54321; $i++) {
$tmp = str_split($i);
if (count(array_diff($range, $tmp)) == 0) {
$arr[] = $tmp;
}
}
return $arr;
}
$arr = create();
foreach ($arr as $k1 => $v1) {
$county['英国'] = $v1[0];
$county['瑞典'] = $v1[1];
$county['丹麦'] = $v1[2];
$county['挪威'] = $v1[3];
$county['德国'] = $v1[4];
if ($county['挪威'] != 1) {//9
continue;
}
foreach ($arr as $k2 => $v2) {
$color['红'] = $v2[0];
$color['白'] = $v2[1];
$color['绿'] = $v2[2];
$color['黄'] = $v2[3];
$color['蓝'] = $v2[4];
if ($county['英国'] != $color['红']) {//1
continue;
}
if ($color['白'] - $color['绿'] != 1) {//4
continue;
}
if (abs($county['挪威'] - $color['蓝']) != 1) {//14
continue;
}
foreach ($arr as $k3 => $v3) {
$pet['鱼'] = $v3[0];
$pet['狗'] = $v3[1];
$pet['鸟'] = $v3[2];
$pet['猫'] = $v3[3];
$pet['马'] = $v3[4];
if ($county['瑞典'] != $pet['狗']) {//2
continue;
}
foreach ($arr as $k4 => $v4) {
$smoke['混合'] = $v4[0];
$smoke['pall'] = $v4[1];
$smoke['dunh'] = $v4[2];
$smoke['blue'] = $v4[3];
$smoke['prin'] = $v4[4];
if ($smoke['pall'] != $pet['鸟']) {//6
continue;
}
if ($color['黄'] != $smoke['dunh']) {//7
continue;
}
if (abs($smoke['混合'] - $pet['猫']) != 1) {//10
continue;
}
if (abs($pet['马'] - $smoke['dunh']) != 1) {//11
continue;
}
if ($county['德国'] != $smoke['prin']) {//13
continue;
}
foreach ($arr as $k5 => $v5) {
$drink['矿泉水'] = $v5[0];
$drink['茶'] = $v5[1];
$drink['咖啡'] = $v5[2];
$drink['牛奶'] = $v5[3];
$drink['啤酒'] = $v5[4];
if ($county['丹麦'] != $drink['茶']) {//3
continue;
}
if ($color['绿'] != $drink['咖啡']) {//5
continue;
}
if ($drink['牛奶'] != 3) {//8
continue;
}
if ($smoke['blue'] != $drink['啤酒']) {//12
continue;
}
if (abs($smoke['混合'] - $drink['矿泉水']) != 1) {//15
continue;
}
print_arr(compact('county', 'color', 'pet', 'smoke', 'drink'));
}
}
}
}
}
/**
* 打印结果
*/
function print_arr($arr)
{
foreach ($arr as $k => $v) {
$sort = array_flip($v);
ksort($sort);
$tmp[] = $sort;
}
foreach ($tmp as $k => $v) {
for ($i = 1; $i <= 5; $i++) {
echo $tmp[$k][$i], "\t";
}
echo "\n\r";
}
}
答案就不放了,可以自己试一下