三叉树解2011年度最变态的迷宫难题

 

        问题出处: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

...

 

        要验证结果正确不正确恐怕不能用计算器,因为这些算式是按从左向右依次运算的,而不是按先乘除后加减的四则运算法则,要用计算器就上括号吧。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值