208
社区成员




汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根子上从下往上按照大小顺序摞着n片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子.子上从下往上按照大小顺序摞着n片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子.并且规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。问应该如何操作?
1、将n-1个盘子从A柱移动到B柱
2、将A柱底下最大的盘子移动至C柱
3、将B柱的n-1个盘子移动至C柱
package Hanoi;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
public class AI {
private static Set<String> list=new HashSet<String>();//保存已经出现过的状态
private static ArrayList<String> slist=new ArrayList<String>();//保存解状态
public static void main(String[] args) {
//建立初始状态
Ta[] ts=new Ta[2];
Gan[] gs=new Gan[3];
StringBuilder sb=new StringBuilder();
for(int i=0;i<ts.length;i++) {
ts[i]=new Ta(i,(char)(i+'A')+"",0);
sb.append(0);
}
list.add(sb.toString());
for(int i=0;i<3;i++) {
gs[i]=new Gan();
}
dfs(ts,gs,0);
//打印解状态
System.out.println(slist);
}
public static boolean dfs(Ta[] ts,Gan[] gs,int index) {
for(int j=0;j<3;j++) {
if(ts[index].index!=j) {
int now=ts[index].index;
StringBuilder sb=new StringBuilder();
for(Ta t:ts) {
if(t!=ts[index])
sb.append(t.index);
else
sb.append(j);
}
if(ts[index].size<gs[j].getTopSize()) {
boolean flag=false;
for(String s:list) {
if(s.equals(sb.toString())) {
flag=true;
break;
}
}
if(!flag) {
//移动到j
ts[index].index=j;
gs[now].list.remove(ts[index]);
gs[j].list.add(ts[index]);
list.add(sb.toString());
slist.add(ts[index].name+"移动到"+(ts[index].index+1));
boolean f=false;
for(int i=0;i<ts.length;i++) {//回溯
if(i!=index)
{
f=dfs(ts,gs,i);//递归
if(f) {
return true;
}
}
}
//成功条件
if(gs[1].list.size()==ts.length&&gs[1].getTop()==ts[0]) {
return true;
}
//放回原位
gs[j].list.remove(ts[index]);
ts[index].index=now;
//slist.add(ts[index].name+"移动到"+now);
}
}
}
}
return false;
}
}
/**
* 汉诺塔
* @author zyf
*
*/
class Ta{
int size;//尺寸
String name;
int index;//在第index个杆子上
public Ta(int size, String name, int index) {
this.size = size;
this.name = name;
this.index = index;
}
}
/**
* 柱子
* @author zyf
*
*/
class Gan{
ArrayList<Ta> list=new ArrayList<Ta>();
public boolean isEmp() {
return list.size()==0;
}
public int getTopSize() {
if(!isEmp())
return list.get(list.size()-1).size;
return Integer.MAX_VALUE;
}
public Ta getTop() {
if(!isEmp())
return list.get(list.size()-1);
return null;
}
}