原题在这里: http://www2.stetson.edu/~efriedma/holiday/2011/index.html 题目: 有这样一个迷宫,从2011开始,不能回头,只能“朝前”走,走出迷宫的时候需要变成2012. 例如从2011开始,有+7,/2两种选择,选择/2后,又有+7,x3/-5三种选择。 解法: 其实就是2011为根的子树,不断的生成下一层的节点,直到节点值为2012。 dfs遍历肯定不现实的,bfs算是比较适合的方法了。不过有更快捷的办法,我使用的是最原始的bfs。 运算方式有四种,位置有三种,分别用枚举表示。 代码: 代码写的很长了,100行以内应该是没问题的,即使是使用我的这种笨方法o(╯□╰)o。为了条理清楚些,就多定义了些函数。 Code Snippet - /*
- * =====================================================================================
- * Filename: puzzle.cpp
- * Description:
- *
- * Version: 1.0
- * Created: 11/16/2012 04:34:49 PM
- *
- * Author: zhy (), izualzhy@163.com
- * =====================================================================================
- */
-
- #include <iostream>
- #include <vector>
- #include <queue>
- #include <string>
- using namespace std;
-
- class PuzzleGuessor {
- public:
- /*可选的数学运算*/
- enum Op {
- OpNone,
- AddSeven,
- DivTwo,
- MultiThree,
- SubFive,
- OpCount
- };
-
- /*位置,由位置和数学运算则可以推断下一步可选的运算方式*/
- enum Position {
- Left,
- Middle,
- Right
- };
-
- /*节点,记录当前的计算结果,位置和到达位置前的运算方式 */
- struct TreeNode {
- TreeNode(double d, Op op, Position position)
- : data(d)
- , oper(op)
- , pos(position)
- {
- }
-
- double data;
- Op oper;
- Position pos;
- vector<TreeNode*> children;
- };
-
- PuzzleGuessor();
- void BuildTree();//构造树
-
- private:
- queue<TreeNode*> q;
- TreeNode* root;
- string OpTable[OpCount];//运算对应的字符串表,输出用
- string result;
- bool CreateNewChildForNode(TreeNode* node);//由节点处根据下一步可进行的运算产生下一层节点
- bool CalcNextFromLeft(TreeNode* node);//在左端时可能的节点
- bool CalcNextFromMiddle(TreeNode* node);//中间位置
- bool CalcNextFromRight(TreeNode* node);//右端
- bool Achieve2012(TreeNode* node);
- bool Find(TreeNode* node, TreeNode* objNode);
- };
-
- PuzzleGuessor::PuzzleGuessor()
- {
- root = new TreeNode(2011.0, OpNone, Left);
- TreeNode* child1 = new TreeNode(root->data + 7, AddSeven, Middle);
- TreeNode* child2 = new TreeNode(root->data / 2, DivTwo, Middle);
- root->children.push_back(child1);
- root->children.push_back(child2);
- q.push(child1);
- q.push(child2);
-
- OpTable[OpNone] = "none";
- OpTable[AddSeven] = "+7";
- OpTable[DivTwo] = "/2";
- OpTable[MultiThree] = "x3";
- OpTable[SubFive] = "-5";
- BuildTree();
- }
-
- void PuzzleGuessor::BuildTree()
- {
- result.clear();
- while (!q.empty())
- {
- TreeNode* node = q.front();
- CreateNewChildForNode(node);
- for ( int i=0; i<node->children.size(); ++i)
- {
- if (node->children[i]->data - 2012 < 1e-6 && 2012 - node->children[i]->data < 1e-6)
- {
- cout << "Achieve 2012!\t" << node->children[i]->data << endl;
- Find(root, node->children[i]);
- cout << result << endl;
- result.clear();
- ///*如果不retunr,则会一直计算下去 */
- //return;
- }
- q.push(node->children[i]);
- }
- q.pop();
- }
- }
-
- bool PuzzleGuessor::Find(TreeNode* node, TreeNode* objNode)
- {
- if (node == NULL)
- return false;
- if (node == objNode)
- {
- result = OpTable[node->oper];
- return true;
- }
- for ( int i=0; i<node->children.size(); ++i)
- {
- if( Find(node->children[i], objNode) )
- {
- //cout << node->data << endl;
- if (OpNone == node->oper)
- result.insert(0, "2011");
- else
- result.insert(0,OpTable[node->oper]);
- return true;
- }
- }
-
- return false;
- }
-
- bool PuzzleGuessor::CreateNewChildForNode(TreeNode* node)
- {
- if (node == NULL)
- return false;
-
- switch (node->pos)
- {
- case Left:
- CalcNextFromLeft(node);
- break;
- case Middle:
- CalcNextFromMiddle(node);
- break;
- case Right:
- CalcNextFromRight(node);
- break;
- }
- }
-
- bool PuzzleGuessor::CalcNextFromLeft(TreeNode* node)
- {
- if (node == NULL)
- return false;
-
- switch (node->oper)
- {
- case AddSeven:
- {
- TreeNode* newNode = new TreeNode(node->data / 2, DivTwo, Middle);
- node->children.push_back(newNode);
- break;
- }
- case DivTwo:
- {
- TreeNode* newNode = new TreeNode(node->data + 7, AddSeven, Middle);
- node->children.push_back(newNode);
- break;
- }
- default:
- return false;
- }
-
- return true;
- }
- bool PuzzleGuessor::CalcNextFromMiddle(TreeNode* node)
- {
- if (node == NULL)
- return false;
-
- if (node->oper == AddSeven || node->oper == DivTwo)
- {
- TreeNode* newNode = new TreeNode(node->data * 3, MultiThree, Right);
- node->children.push_back(newNode);
- newNode = new TreeNode(node->data - 5, SubFive, Right);
- node->children.push_back(newNode);
-
- if (node->oper == AddSeven)
- {
- TreeNode* newNode = new TreeNode(node->data / 2, DivTwo, Left);
- node->children.push_back(newNode);
- }
- else if (node->oper == DivTwo)
- {
- TreeNode* newNode = new TreeNode(node->data + 7, AddSeven, Left);
- node->children.push_back(newNode);
- }
- }
- else if (node->oper == MultiThree || node->oper == SubFive)
- {
- TreeNode* newNode = new TreeNode(node->data + 7, AddSeven, Left);
- node->children.push_back(newNode);
- newNode = new TreeNode(node->data / 2, DivTwo ,Left);
- node->children.push_back(newNode);
-
- if (node->oper == MultiThree)
- {
- TreeNode* newNode = new TreeNode(node->data - 5, DivTwo, Right);
- node->children.push_back(newNode);
- }
- else if (node->oper == SubFive)
- {
- TreeNode* newNode = new TreeNode(node->data * 3, MultiThree, Right);
- node->children.push_back(newNode);
- }
- }
- else
- {
- return false;
- }
-
- return true;
- }
-
- bool PuzzleGuessor::CalcNextFromRight(TreeNode* node)
- {
- if (node == NULL)
- return false;
-
- switch (node->oper)
- {
- case MultiThree:
- {
- TreeNode* newNode = new TreeNode(node->data - 5, SubFive, Middle);
- node->children.push_back(newNode);
- break;
- }
- case SubFive:
- {
- TreeNode* newNode = new TreeNode(node->data * 3, MultiThree, Middle);
- node->children.push_back(newNode);
- break;
- }
- default:
- return false;
- }
-
- return true;
- }
-
- int main()
- {
- PuzzleGuessor guesser;
- return 0;
- }
部分输出: Achieve 2012! 2012 2011+7/2+7/2+7x3-5/2+7x3-5/2+7x3-5x3-5/2+7/2+7/2+7/2+7x3-5+7 Achieve 2012! 2012 2011+7/2+7/2+7x3-5/2+7x3-5/2+7-5x3+7/2+7/2+7/2+7/2x3-5x3-5+7 Achieve 2012! 2012 2011+7/2+7/2+7x3-5x3-5+7/2+7/2+7/2+7/2x3-5/2+7x3-5x3-5+7/2+7 Achieve 2012! 2012 2011+7/2+7/2+7x3-5x3-5+7/2+7/2+7/2+7/2x3-5/2+7-5x3/2+7x3-5+7 Achieve 2012! 2012 2011+7/2+7/2+7-5x3/2+7x3-5+7/2+7/2+7/2x3-5/2+7x3-5x3-5+7/2+7 Achieve 2012! 2012 2011+7/2+7/2+7-5x3/2+7x3-5+7/2+7/2+7/2x3-5/2+7-5x3/2+7x3-5+7 Achieve 2012! 2012 2011+7/2+7/2+7-5x3/2+7/2+7x3-5/2+7-5x3+7/2+7/2x3-5x3-5+7/2+7 Achieve 2012! 2012 2011+7/2+7/2+7-5x3/2+7/2+7x3-5/2+7-5x3+7/2+7/2-5x3/2+7x3-5+7 Achieve 2012! 2012 2011+7/2+7/2+7-5x3/2+7/2+7-5x3/2+7x3-5/2+7x3-5+7/2+7/2x3-5+7
|
|
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
---|
28 | 29 | 30 | 31 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
常用链接
留言簿(5)
随笔分类(18)
随笔档案(16)
最新随笔
搜索
积分与排名
最新随笔
最新评论
阅读排行榜
评论排行榜
|
|