八数码难题

题目描述

在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。

输入输出格式

输入格式:

输入初试状态,一行九个数字,空格用0表示

 

输出格式:

只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)

 

输入输出样例

输入样例#1:
283104765
输出样例#1:
4
代码实现:
 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<map>
 5 using namespace std;
 6 map <string,int>v;
 7 map <string,int>step;
 8 int a,b,t,head=0,tail=0;
 9 int bh[]={-3,-1,1,3},wz[100000],tou[100000];
10 string s,rs("123804765"),dl[100000],ns;
11 int main(){
12     cin>>s;
13     a=s.find('0');//a是‘0’的位置。
14     wz[head]=a;
15     tou[head]=1;
16     dl[head++]=s;
17     wz[head]=4;
18     tou[head]=2;
19     dl[head++]=rs;
20     v[s]=1;
21     while(tail<=head){
22         a=wz[tail];
23         t=tou[tail];
24         s=dl[tail++];
25         b=step[s];
26         for(int i=0;i<4;i++){
27             ns=s;
28             if(i==0&&a>2){
29                 ns[a]=s[a+bh[i]];ns[a+bh[i]]=s[a];
30             }
31             if(i==1&&a!=0&&a!=3&&a!=6){
32                 ns[a]=s[a+bh[i]];ns[a+bh[i]]=s[a];
33             }
34             if(i==2&&a!=2&&a!=5&&a!=8){
35                 ns[a]=s[a+bh[i]];ns[a+bh[i]]=s[a];
36             }
37             if(i==3&&a<6){
38                 ns[a]=s[a+bh[i]];ns[a+bh[i]]=s[a];
39             }
40             if(v[ns]!=t){
41                 if(!v[ns]){
42                     v[ns]=t;wz[head]=a+bh[i];tou[head]=t;
43                     dl[head++]=ns;step[ns]=b+1;
44                 }
45                 else{cout<<b+1+step[ns]<<endl;return 0;}    
46             }
47         }
48     }
49     return 0;
50 }
很久之前的代码了,我其实也不知道现在能不能打出来。(现在敲应该也就30+吧,这是病。)
题目来源:CODE[VS]
posted @ 2017-02-03 09:36  J_william  阅读(224)  评论(0编辑  收藏  举报