问题出处:Matrix67: My Blog ? Blog Archive ? 2011年度最变态的迷宫难题
问题描述:“下面大家将会看到的是一个极其简单而又极其复杂的“迷宫”,这无疑是我在本年度见到的最变态的谜题:从左边入口处的 2011 进去,在迷宫里转悠,最后变成 2012 从右边出来。你可以在迷宫里转圈,可以重复之前走过的路,但不能往回退着走。”
你能成功走出来吗?
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
答案:2011+7/2+7/2+7-5*3/2+7/2+7*3-5/2+7/2+7-5*3-5*3/2+7-5*3/2+7-5=2012
用三叉树解一下。如果不设终止条件直接建树很快就会溢出,所以设定了树的深度和计算值两个终止条件。计算值终止条件设为值大于10000或小于-10000终止子树搜索。具体搜索过程从左向右经过加7路径后偶数有三条路径:÷2,×3,-5;奇数有两条路径:×3,-5。从右向左经过+7路径后只有一条路径:÷2。从左向右经过÷2路径后有三条路径:+7,×3,-5。从右向左经过÷2路径后只有一条路径:+7。从左向右经过×3路径后只有一条路径:-5。从右向左经过×3路径后偶数有三条路径:+7,÷2,-5;奇数有两条路径:+7,-5。从左向右经过-5路径后是2012找到结果,否则只有一条路径:×3。从右向左经过-5路径后偶数有三条路径:+7,÷2,×3;奇数有两条路径:+7,×3。
因为2012不能被3整除所以满足条件的结果最后只能是自左向右经过-5的路径。找到结果后利用parent指针标记自根下来的路径用于显示结果。
/* 三叉树求解2011年度最变态的迷宫难题 */
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
typedef struct tagtree
{
char op;
int value;
struct tagtree *parent;
struct tagtree *lchild;
struct tagtree *mchild;
struct tagtree *rchild;
}tree;
#define Alloctree ((tree *)malloc(sizeof(tree)))
void createchild(tree **parent, int level);
void destory(tree **root);
void markroute(tree *treenode);
int finded = 0; /* 全局变量,找到结果的标记 */
int MAXDEPTH; /* 全局变量,搜索深度 */
int main(void)
{
tree *root;
tree *p;
for (MAXDEPTH = 5; MAXDEPTH <= 150; MAXDEPTH += 5)
{
finded = 0;
root = Alloctree;
root->value = 2011;
root->op = 0;
root->lchild = Alloctree;
root->mchild = NULL;
root->rchild = NULL;
root->lchild->lchild = NULL;
root->lchild->mchild = NULL;
root->lchild->rchild = NULL;
root->lchild->parent = root;
root->lchild->value = 2018;
root->lchild->op = 1;
createchild(&(root->lchild), 2);
if (finded)
{
printf("\n2011");
p = root->lchild;
while(1)
{
if ((p-> op & 0xf) == 1 || (p-> op & 0xf) == 2)
printf("+7");
else if ((p-> op & 0xf) == 3 || (p-> op & 0xf) == 4)
printf("/2");
else if ((p-> op & 0xf) == 5 || (p-> op & 0xf) == 6)
printf("*3");
else
printf("-5");
if (p->lchild == NULL)
break;
if ((p->lchild->op & 0x10) == 0x10)
p = p->lchild;
else if ((p->mchild->op & 0x10) == 0x10)
p = p->mchild;
else
p = p->rchild;
}
printf("=2012\n");
}
destory(&root);
}
getch();
}
/*
op记录路线方向:
1-从左向右经过7,2-从右向左经过7,3-从左向右经过2,4-从右向左经过2,
5-从左向右经过3,6-从右向左经过3,7-从左向右经过5,8-从右向左经过5
op: 1-7-L,2-7-R,3-2-L,4-2-R,5-3-L,6-3-R,7-5-L,8-5-R
*/
void createchild(tree **parent, int level)
{
if (*parent == NULL)
return;
if (finded || level == MAXDEPTH)
return;
if ((*parent)->value == 2012 && (*parent)->op == 7)
{
finded = 1;
markroute(*parent);
return;
}
if ((*parent)->value < -10000 || (*parent)->value > 10000)
return;
(*parent)->lchild = NULL;
(*parent)->mchild = NULL;
(*parent)->rchild = NULL;
/* op: 1-7-L,2-7-R,3-2-L,4-2-R,5-3-L,6-3-R,7-5-L,8-5-R */
if ((*parent)->op == 1)
{
if (((*parent)->value & 1) == 0)
{
(*parent)->lchild = Alloctree;
(*parent)->lchild->value = (*parent)->value >> 1;
(*parent)->lchild->op = 4;
(*parent)->lchild->lchild = NULL;
(*parent)->lchild->mchild = NULL;
(*parent)->lchild->rchild = NULL;
(*parent)->lchild->parent = *parent;
(*parent)->mchild = Alloctree;
(*parent)->mchild->value = (*parent)->value * 3;
(*parent)->mchild->op = 5;
(*parent)->mchild->lchild = NULL;
(*parent)->mchild->mchild = NULL;
(*parent)->mchild->rchild = NULL;
(*parent)->mchild->parent = *parent;
(*parent)->rchild = Alloctree;
(*parent)->rchild->value = (*parent)->value - 5;
(*parent)->rchild->op = 7;
(*parent)->rchild->lchild = NULL;
(*parent)->rchild->mchild = NULL;
(*parent)->rchild->rchild = NULL;
(*parent)->rchild->parent = *parent;
createchild(&(*parent)->lchild, level + 1);
createchild(&(*parent)->mchild, level + 1);
createchild(&(*parent)->rchild, level + 1);
}
else
{
(*parent)->lchild = Alloctree;
(*parent)->lchild->value = (*parent)->value * 3;
(*parent)->lchild->op = 5;
(*parent)->lchild->lchild = NULL;
(*parent)->lchild->mchild = NULL;
(*parent)->lchild->rchild = NULL;
(*parent)->lchild->parent = *parent;
(*parent)->mchild = Alloctree;
(*parent)->mchild->value = (*parent)->value - 5;
(*parent)->mchild->op = 7;
(*parent)->mchild->lchild = NULL;
(*parent)->mchild->mchild = NULL;
(*parent)->mchild->rchild = NULL;
(*parent)->mchild->parent = *parent;
createchild(&(*parent)->lchild, level + 1);
createchild(&(*parent)->mchild, level + 1);
}
}
else if ((*parent)->op == 2)
{
if (((*parent)->value & 1) == 0)
{
(*parent)->lchild = Alloctree;
(*parent)->lchild->value = (*parent)->value >> 1;
(*parent)->lchild->op = 3;
(*parent)->lchild->lchild = NULL;
(*parent)->lchild->mchild = NULL;
(*parent)->lchild->rchild = NULL;
(*parent)->lchild->parent = *parent;
createchild(&(*parent)->lchild, level + 1);
}
}
else if ((*parent)->op == 3)
{
(*parent)->lchild = Alloctree;
(*parent)->lchild->value = (*parent)->value + 7;
(*parent)->lchild->op = 2;
(*parent)->lchild->lchild = NULL;
(*parent)->lchild->mchild = NULL;
(*parent)->lchild->rchild = NULL;
(*parent)->lchild->parent = *parent;
(*parent)->mchild = Alloctree;
(*parent)->mchild->value = (*parent)->value * 3;
(*parent)->mchild->op = 5;
(*parent)->mchild->lchild = NULL;
(*parent)->mchild->mchild = NULL;
(*parent)->mchild->rchild = NULL;
(*parent)->mchild->parent = *parent;
(*parent)->rchild = Alloctree;
(*parent)->rchild->value = (*parent)->value - 5;
(*parent)->rchild->op = 7;
(*parent)->rchild->lchild = NULL;
(*parent)->rchild->mchild = NULL;
(*parent)->rchild->rchild = NULL;
(*parent)->rchild->parent = *parent;
createchild(&(*parent)->lchild, level + 1);
createchild(&(*parent)->mchild, level + 1);
createchild(&(*parent)->rchild, level + 1);
}
else if ((*parent)->op == 4)
{
(*parent)->lchild = Alloctree;
(*parent)->lchild->value = (*parent)->value + 7;
(*parent)->lchild->op = 1;
(*parent)->lchild->lchild = NULL;
(*parent)->lchild->mchild = NULL;
(*parent)->lchild->rchild = NULL;
(*parent)->lchild->parent = *parent;
createchild(&(*parent)->lchild, level + 1);
}
else if ((*parent)->op == 5)
{
(*parent)->lchild = Alloctree;
(*parent)->lchild->value = (*parent)->value - 5;
(*parent)->lchild->op = 8;
(*parent)->lchild->lchild = NULL;
(*parent)->lchild->mchild = NULL;
(*parent)->lchild->rchild = NULL;
(*parent)->lchild->parent = *parent;
createchild(&(*parent)->lchild, level + 1);
}
else if ((*parent)->op == 6)
{
if (((*parent)->value & 1) == 0)
{
(*parent)->lchild = Alloctree;
(*parent)->lchild->value = (*parent)->value >> 1;
(*parent)->lchild->op = 4;
(*parent)->lchild->lchild = NULL;
(*parent)->lchild->mchild = NULL;
(*parent)->lchild->rchild = NULL;
(*parent)->lchild->parent = *parent;
(*parent)->mchild = Alloctree;
(*parent)->mchild->value = (*parent)->value + 7;
(*parent)->mchild->op = 2;
(*parent)->mchild->lchild = NULL;
(*parent)->mchild->mchild = NULL;
(*parent)->mchild->rchild = NULL;
(*parent)->mchild->parent = *parent;
(*parent)->rchild = Alloctree;
(*parent)->rchild->value = (*parent)->value - 5;
(*parent)->rchild->op = 7;
(*parent)->rchild->lchild = NULL;
(*parent)->rchild->mchild = NULL;
(*parent)->rchild->rchild = NULL;
(*parent)->rchild->parent = *parent;
createchild(&(*parent)->lchild, level + 1);
createchild(&(*parent)->mchild, level + 1);
createchild(&(*parent)->rchild, level + 1);
}
else
{
(*parent)->lchild = Alloctree;
(*parent)->lchild->value = (*parent)->value + 7;
(*parent)->lchild->op = 2;
(*parent)->lchild->lchild = NULL;
(*parent)->lchild->mchild = NULL;
(*parent)->lchild->rchild = NULL;
(*parent)->lchild->parent = *parent;
(*parent)->mchild = Alloctree;
(*parent)->mchild->value = (*parent)->value - 5;
(*parent)->mchild->op = 7;
(*parent)->mchild->lchild = NULL;
(*parent)->mchild->mchild = NULL;
(*parent)->mchild->rchild = NULL;
(*parent)->mchild->parent = *parent;
createchild(&(*parent)->lchild, level + 1);
createchild(&(*parent)->mchild, level + 1);
}
}
else if ((*parent)->op == 7)
{
(*parent)->lchild = Alloctree;
(*parent)->lchild->value = (*parent)->value * 3;
(*parent)->lchild->op = 6;
(*parent)->lchild->lchild = NULL;
(*parent)->lchild->mchild = NULL;
(*parent)->lchild->rchild = NULL;
(*parent)->lchild->parent = *parent;
createchild(&(*parent)->lchild, level + 1);
}
else if ((*parent)->op == 8)
{
if (((*parent)->value & 1) == 0)
{
(*parent)->lchild = Alloctree;
(*parent)->lchild->value = (*parent)->value >> 1;
(*parent)->lchild->op = 4;
(*parent)->lchild->lchild = NULL;
(*parent)->lchild->mchild = NULL;
(*parent)->lchild->rchild = NULL;
(*parent)->lchild->parent = *parent;
(*parent)->mchild = Alloctree;
(*parent)->mchild->value = (*parent)->value + 7;
(*parent)->mchild->op = 2;
(*parent)->mchild->lchild = NULL;
(*parent)->mchild->mchild = NULL;
(*parent)->mchild->rchild = NULL;
(*parent)->mchild->parent = *parent;
(*parent)->rchild = Alloctree;
(*parent)->rchild->value = (*parent)->value * 3;
(*parent)->rchild->op = 5;
(*parent)->rchild->lchild = NULL;
(*parent)->rchild->mchild = NULL;
(*parent)->rchild->rchild = NULL;
(*parent)->rchild->parent = *parent;
createchild(&(*parent)->lchild, level + 1);
createchild(&(*parent)->mchild, level + 1);
createchild(&(*parent)->rchild, level + 1);
}
else
{
(*parent)->lchild = Alloctree;
(*parent)->lchild->value = (*parent)->value + 7;
(*parent)->lchild->op = 2;
(*parent)->lchild->lchild = NULL;
(*parent)->lchild->mchild = NULL;
(*parent)->lchild->rchild = NULL;
(*parent)->lchild->parent = *parent;
(*parent)->mchild = Alloctree;
(*parent)->mchild->value = (*parent)->value * 3;
(*parent)->mchild->op = 5;
(*parent)->mchild->lchild = NULL;
(*parent)->mchild->mchild = NULL;
(*parent)->mchild->rchild = NULL;
(*parent)->mchild->parent = *parent;
createchild(&(*parent)->lchild, level + 1);
createchild(&(*parent)->mchild, level + 1);
}
}
}
/* 标记结果路径 */
void markroute(tree *treenode)
{
tree *parent = treenode;
while(parent->op != 0)
{
parent->op |= 0x10;
parent = parent->parent;
}
}
void destory(tree **root)
{
if (*root == NULL)
return;
destory(&(*root)->lchild);
destory(&(*root)->mchild);
destory(&(*root)->rchild);
free(*root);
*root = NULL;
}
满足条件的结果不止一个:
2011+7/2+7/2+7-5*3/2+7/2+7*3-5/2+7/2+7-5*3-5*3/2+7-5*3/2+7-5=2012
2011+7/2+7/2+7*3-5/2+7*3-5/2+7/2+7/2+7-5*3/2+7/2+7/2+7/2+7*3-5*3-5+7/2-5*3-5*3/2+7-5*3/2+7-5=2012
2011+7/2+7/2+7*3-5/2+7*3-5/2+7/2+7/2+7*3-5/2+7*3-5/2+7*3-5/2+7/2+7*3-5/2+7-5*3+7/2+7/2-5*3+7/2*3-5+7/2-5*3/2+7-5=2012
2011+7/2+7/2+7*3-5/2+7*3-5/2+7/2+7/2+7*3-5/2+7*3-5/2+7*3-5/2+7/2+7*3-5/2+7/2+7/2+7/2+7/2+7-5*3/2+7-5*3+7/2-5*3/2+7-5*3-5*3+7/2*3-5+7/2-5*3/2+7-5=2012
2011+7/2+7/2+7*3-5/2+7*3-5/2+7/2+7/2+7*3-5/2+7*3-5/2+7*3-5/2+7/2+7*3-5/2+7/2+7/2+7/2+7/2+7*3-5/2+7*3-5/2+7*3-5/2+7/2+7/2+7*3-5*3-5+7/2-5*3-5*3/2+7-5*3/2+7-5=2012
...
要验证结果正确不正确恐怕不能用计算器,因为这些算式是按从左向右依次运算的,而不是按先乘除后加减的四则运算法则,要用计算器就上括号吧。