八数码难题

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 }
原文地址:https://www.cnblogs.com/sssy/p/6752946.html