九连环解法java版

来源:互联网 发布:女士运动内衣品牌知乎 编辑:程序博客网 时间:2024/04/28 10:13

之前想写写试试,只写了个开头,最近补完了,试了下跑的还正常。

功能上能指定各个环是否在杆上,可以按拆卸或安装打印解的步骤。


方法两种,都用到了递归,递归的都是为了处理的n个环,需要前n-2个环不在杆,第n-1个环在杆。

方法2里递归直接做了上环下环动作,方法1里递归只是为了找到是否从第一个环开始解。


关于方法1:

九连环解熟了以后,每次只要确定是否从第一个开始解,然后只靠手熟练,不用思考就能解。

分析一下,九连环里任何时刻最多只能有俩动作:一个环上杆、另一个环下杆,选其中一个动作做后,最多还是只有俩动作(解开后就只有一个动作了)。

只要不出现一个环连续重复操作,总会遇到把九连环解开或安装上的时候。

方法1就这个意思。


package com.superzlc.zlctest.game;public class Jiulianhuan {public static void main(String[] args) {Jiulianhuan t = new Jiulianhuan();//     -999999999-t.init("000000009");t.print(0);t.answer1(true);// t.answer2(true);}// ---------------------// 答案1:递归获取从第几个开始解,然后按习惯解。基于任意时刻只能操作最多俩环,每个环只能是上或下void answer1(boolean forAllDown) {analyse(forAllDown);if (!isFind) {return;}Huan start = this.isFirst ? this.getFirstCanChange() : this.getLastCanChange();System.out.println("从第" + (start.index + 1) + "开始解");while (true) {// 任意时刻,都是只能操作最多俩环,每个环只能是上或下if (isFirst) {this.getFirstCanChange().change();} else {this.getLastCanChange().change();}isFirst = !isFirst;print(++count);if (forAllDown) {if (this.isAllDown())break;} else {if (this.isAllUp())break;}}}private boolean isFind; // 是否找到从第几个开始解private boolean isFirst; // 是否从第1个开始解// 分析从哪个开始解private void analyse(boolean forAllDown) {Huan h = this.last;if (forAllDown) {while (h != null) {if (isFind)return;if (h.isUp()) {needChange(h);}h = h.left;}} else {while (h != null) {if (isFind)return;if (h.isDown()) {needChange(h);}h = h.left;}}}// 递归调用获取从哪个开始解private void needChange(Huan h) {if (isFind)return;Huan left = h.left;if (h.canChange()) {isFind = true;isFirst = h.isFirst();return;}if (left != null) {if (left.isDown()) {needChange(left);}left = left.left;while (left != null) {if (isFind)break;if (left.isUp()) {needChange(left);}left = left.left;}}}// ---------------------// 答案2:递归求解void answer2(boolean forAllDown) {Huan h = this.last;if (forAllDown) {while (h != null) {if (h.isUp()) {execChange(h);}h = h.left;}} else {while (h != null) {if (h.isDown()) {execChange(h);}h = h.left;}}}// 递归调用解private void execChange(Huan h) {Huan left = h.left;// 保证能changeif (left != null) {// 左边第一个保证是up的if (left.isDown()) {execChange(left);}// 左边更多个保证是down的left = left.left;while(left != null) {if (left.isUp()) {execChange(left);}left = left.left;}}h.change();print(++count);}// ------------------------------------------private static final int length = 9;private Huan first;private Huan last;private Huan[] huans;private int count = 0;Jiulianhuan() {huans = new Huan[length];for (int i = 0; i < length; i++) {huans[i] = new Huan(i, true);}first = huans[0];last = huans[length - 1];// linkfor (int i = 0; i < length; i++) {Huan left = i - 1 >= 0 ? huans[i - 1] : null;Huan right = i + 1 < length ? huans[i + 1] : null;huans[i].link(left, right);}}// 以字符串10101101或ududduudu初始化,1/u为upvoid init(String ss) {if (ss == null || ss.length() == 0)return;for (int i = 0; i < length; i++) {if (i < ss.length()) {char c = ss.charAt(i);huans[i].setStatus(c == '1' || c == 'u' || c == '9');}}}boolean isAllDown() {if (this.first.isUp() || this.last.isUp())return false;for (Huan t : huans) {if (t.isUp())return false;}return true;}boolean isAllUp() {if (this.first.isDown() || this.last.isDown())return false;for (Huan t : huans) {if (t.isDown())return false;}return true;}Huan getFirstCanChange() {// 就是第一个return this.first;}Huan getLastCanChange() {// 第k个满足:ddddukHuan h = this.first;while (h != null) {if (h.isUp()) {return h.right;}h = h.right;}return null;}void print(int idx) {String str1 = idx > 0 ? String.format("%4d: ", idx) : "init: ";for (Huan t : huans) {if (t.isUp()) {str1 += "9";} else {str1 += "o";}}System.out.println(str1);}static class Huan {public Huan(int index, boolean up) {this.index = index;this.up = up;}public void link(Huan left, Huan right) {this.left = left;this.right = right;}Huan left;Huan right;int index;boolean up;//boolean isFirst() {return left == null;}boolean isLast() {return right == null;}//boolean canChange() {if (isFirst()) {// 第一个允许随时能切换return true;} else {// 非第一个k要满足ddddukif (left.isDown()) {return false;}Huan t = left.left;while (t != null) {if (t.isUp()) {return false;}t = t.left;}return true;}}boolean change() {if (canChange()) {if (isUp())setDown();elsesetUp();return true;} else {return false;}}//void setUp() {setStatus(true);}void setDown() {setStatus(false);}void setStatus(boolean up) {this.up = up;}boolean isUp() {return up;}boolean isDown() {return !isUp();}}}


0 0
原创粉丝点击