3243 - 八数码
时间限制 : 1 秒
内存限制 : 256 MB
在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。
题目输入
输入初试状态,一行九个数字,空格用0表示
题目输出
只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)
输入/输出样例
输入格式
283104765
输出格式
4
C++解答
/* Name: 八数码 Date: 14/10/14 20:21 Description: IDA* */ #include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> using namespace std; int now[10]; char c; int to[10]={0,1,2,3,8,0,4,7,6,5}; int pos0=0,deep=0,h; int f(){ int fnow[10]; int fto[10]; int tot=0; for(int i=1;i<=9;++i){ fnow[now[i]]=i-1; fto[to[i]]=i-1; } for(int i=1;i<9;++i){ tot+=abs(fnow[i]/3-fto[i]/3)+abs(fnow[i]%3-fto[i]%3); } return tot; } void dfs(int ans,int pos){ h=f(); if(h+ans>deep) return; if(ans==deep) { cout<<ans<<endl; exit(0); } if(pos!=1&&pos!=4&&pos!=7){ swap(now[pos],now[pos-1]); dfs(ans+1,pos-1); swap(now[pos],now[pos-1]); } if(pos!=3&&pos!=6&&pos!=9){ swap(now[pos],now[pos+1]); dfs(ans+1,pos+1); swap(now[pos],now[pos+1]); } if(pos>3){ swap(now[pos],now[pos-3]); dfs(ans+1,pos-3); swap(now[pos],now[pos-3]); } if(pos<7){ swap(now[pos],now[pos+3]); dfs(ans+1,pos+3); swap(now[pos],now[pos+3]); } } int main(){ /*freopen("1.in","r",stdin); for(int i=1;i<=9;++i){ cin>>now[i]; if(now[i]==0) pos0=i; }*/ for(int i=1;i<=9;++i){ cin>>c; now[i]=(int)c-48; if(now[i]==0) pos0=i; } while(1){ dfs(0,pos0); ++deep; } }
Java解答
import java.util.ArrayList; import java.util.HashSet; import java.util.Scanner; public class Main { int[] dx = {-3,3,-1,1}; public Main(){ Scanner sc=new Scanner(System.in); String start = sc.nextLine(),end = "123804765"; // 起始和结束状态 HashSet<String> judge = new HashSet<>(); judge.add(start); ArrayList<State> AL=new ArrayList<State>(); AL.add(new State(start.toCharArray(),0)); while(!AL.isEmpty()){ //System.out.println(index); State current=AL.remove(0); if(String.valueOf(current.type).equals(end)){ System.out.println(current.step); return; } int blank;// 空格的位置 for(blank = 0;blank<9;blank++)if (current.type[blank] == '0') break; for (int dt:dx) { if ((blank<3 && dt==-3) || (blank>5 && dt==3) || (blank%3==0 && dt==-1) || (blank%3==2 && dt==1)) continue;//不合法的情形,直接跳过 else { char[] type_new = new char[9]; for (int i = 0; i < 9 ; i++) type_new[i] = current.type[i]; type_new[blank] = type_new[blank+dt]; type_new[blank+dt] = '0'; String newS = String.valueOf(type_new); if(!judge.contains(newS)) { State newState = new State(type_new,current.step+1); AL.add(newState); judge.add(newS); } } } } } public static void main(String[] args) { Main tk=new Main(); } class State{ //状态 char[] type; //格局 int step; //步数 public State(char[] type, int step) { this.type = type; this.step = step; } } }