3243 - 八数码

通过次数

0

提交次数

0

时间限制 : 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;
        }
    }
}