問題出處: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
...
要驗證結果正確不正確恐怕不能用計算器,因爲這些算式是按從左向右依次運算的,而不是按先乘除後加減的四則運算法則,要用計算器就上括號吧。