首页 > 代码库 > 八数码难题

八数码难题

1225 八数码难题

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 钻石 Diamond
 
题目描述 Description

Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们.

 

问题描述

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

输入描述 Input Description

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

输出描述 Output Description

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

样例输入 Sample Input

283104765

样例输出 Sample Output

4

数据范围及提示 Data Size & Hint

详见试题

关于一个666的深搜神奇的wa题解233,就这样莫名其妙的wa

 1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int mp[4][4]; 5 int move[6]={0,1,0,-1,0},ans; 6 bool check() 7 { 8     if(mp[1][1]!=1||mp[1][2]!=2||mp[1][3]!=3||mp[2][1]!=8||mp[2][2]!=0||mp[2][3]!=4||mp[3][1]!=7||mp[3][2]!=6||mp[3][3]!=5)return 0; 9     else return 1;10 }11 bool can(int a,int b)12 {13     if(a>=1&&a<=3&&b>=1&&b<=3)return 1;14     return 0;15 }16 bool dfs(int x,int y,int step)17 {18     if(step==ans)19     {20         if(check())return 1;else return 0;21     }22     int next_x,next_y;23     for(int i=0;i<4;i++)24     {25         next_x=x+move[i];26         next_y=y+move[i+1];27         if(can(next_x,next_y))28         {29             swap(mp[x][y],mp[next_x][next_y]);30             if(dfs(next_x,next_y,step+1))return 1;31             swap(mp[x][y],mp[next_x][next_y]);32         }33     }34 }35 int main()36 {37     string a;int c=0;38     cin>>a;39     int x,y;40     for(int i=1;i<=3;i++)41     for(int j=1;j<=3;j++)42     {43         mp[i][j]=int(a[c++]-48);44         if(mp[i][j]==0)45         {x=i;y=j;}    46     }47     for(ans=1;;ans++)48     {49         if(dfs(x,y,0))50         {break;}51     }52     printf("%d",ans);53     return 0;54 }

 

 

八数码难题