三叉樹解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

...

 

        要驗證結果正確不正確恐怕不能用計算器,因爲這些算式是按從左向右依次運算的,而不是按先乘除後加減的四則運算法則,要用計算器就上括號吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章