首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

意趣迷宫 F(2011) = 2012 , 从2011走到2012

2012-11-25 
趣味迷宫F(2011) 2012 , 从2011走到2012如上图,入口2011,经过加减乘除后到达出口2012。规则:1、不能连续执

趣味迷宫 F(2011) = 2012 , 从2011走到2012

意趣迷宫  F(2011) = 2012 , 从2011走到2012

如上图,入口2011,经过加减乘除后到达出口2012。

规则:1、不能连续执行两次操作;2、方向必须”向前“。

具体例子:从/2到*3后,只能执行-5,不能掉头执行/2或者+7(规则2),更加不能够再次*3(规则1)


在微博 http://weibo.com/1915548291/z4eTPtAnv 发现此问题。此微博的评论有其他同学更高效的算法(A*算法、双向BFS etc.),有兴趣请点击~

问题源于 http://www2.stetson.edu/~efriedma/holiday/2011/index.html

在Matrix67的博客有介绍 http://www.matrix67.com/blog/archives/4790


基本思路:使用BFS或者DFS搜索以2011为根的树即可。

另外:1、根据规则2,必须要处理好计算的方向问题:例如 *3后有可能从左侧进入-5,也有可能从右侧。

    2、注意到 2012不能被3整除,所以唯一的可能的最后操作就是 “左侧进入”的 *3  或者 +7 或者 /2 之后的-5。

    3、进行简单的重复状态判定。为了简便起见,这里仅判定 数值+操作 是否重复了:对这两个因子做简单的哈希处理即可。

======================

枚举 操作+方向:

public From2011To2012_SimpleDFS(int en, int ex) {this.entrance = en;this.exit = ex;}private void dfsOrNot(Node n,int level){if(!values.contains(n.hashCode())){values.add(n.hashCode());dfs(n,level);values.remove(n.hashCode());}}private void dfs(Node n, int level){visitedNodes++;if (n.value == exit && n.od == OperationAndDirection.SUB5_RIGHT){solutions++;Stack<OperationAndDirection> operations = new Stack<OperationAndDirection>();while(n.parent!=null){operations.push(n.od);n = n.parent;}System.out.print(this.entrance);while(!operations.empty()) {OperationAndDirection op = operations.pop();if(op == OperationAndDirection.ADD7_LEFT || op == OperationAndDirection.ADD7_RIGHT){System.out.print(" +7");}else if(op == OperationAndDirection.SUB5_LEFT || op == OperationAndDirection.SUB5_RIGHT){System.out.print(" -5");}else if(op == OperationAndDirection.MUL3_LEFT || op == OperationAndDirection.MUL3_RIGHT){System.out.print(" *3");}else if(op == OperationAndDirection.DIV2_LEFT || op == OperationAndDirection.DIV2_RIGHT){System.out.print(" /2");}}System.out.println(" = " + this.exit);}if(level == 40){return;}else{int p = n.value;switch (n.od) {case START:dfsOrNot(new Node(entrance+7,OperationAndDirection.ADD7_RIGHT,n),level+1);dfsOrNot(new Node(entrance/2,OperationAndDirection.DIV2_RIGHT,n),level+1);break;case SUB5_RIGHT:dfsOrNot(new Node(p*3,OperationAndDirection.MUL3_LEFT,n),level+1);break;case SUB5_LEFT:dfsOrNot(new Node(p+7,OperationAndDirection.ADD7_LEFT,n),level+1);dfsOrNot(new Node(p/2,OperationAndDirection.DIV2_LEFT,n),level+1);dfsOrNot(new Node(p*3,OperationAndDirection.MUL3_RIGHT,n),level+1);break;case ADD7_RIGHT:dfsOrNot(new Node(p-5,OperationAndDirection.SUB5_RIGHT,n),level+1);dfsOrNot(new Node(p/2,OperationAndDirection.DIV2_LEFT,n),level+1);dfsOrNot(new Node(p*3,OperationAndDirection.MUL3_RIGHT,n),level+1);break;case ADD7_LEFT:dfsOrNot(new Node(p/2,OperationAndDirection.DIV2_RIGHT,n),level+1);break;case MUL3_RIGHT:dfsOrNot( new Node(p-5,OperationAndDirection.SUB5_LEFT,n),level+1);break;case MUL3_LEFT:dfsOrNot(new Node(p+7,OperationAndDirection.ADD7_LEFT,n),level+1);dfsOrNot(new Node(p-5,OperationAndDirection.SUB5_RIGHT,n),level+1);dfsOrNot(new Node(p/2,OperationAndDirection.DIV2_LEFT,n),level+1);break;case DIV2_RIGHT:dfsOrNot(new Node(p+7,OperationAndDirection.ADD7_LEFT,n),level+1);dfsOrNot(new Node(p-5,OperationAndDirection.SUB5_RIGHT,n),level+1);dfsOrNot(new Node(p*3,OperationAndDirection.MUL3_RIGHT,n),level+1);break;case DIV2_LEFT:dfsOrNot(new Node(p+7,OperationAndDirection.ADD7_RIGHT,n),level+1);break;default:break;}}}public void compute(){Node start = new Node(this.entrance,OperationAndDirection.START,null);dfs(start,1);System.out.println(visitedNodes + " nodes were visited.");System.out.println(solutions + " solutions.");}


BFS找到了最优解(执行了26次计算)如下:

2011 /2 +7 /2 +7 /2 +7 /2 +7 /2 *3 -5 *3 -5 +7 /2 -5 *3 -5 *3 /2 +7 -5 *3 /2 +7 -5 = 2012


而对于DFS,限定搜索深度为30层的结果如下:

28681973 nodes were visited.
212 solutions.



热点排行