【CodeVS】 p1225 八数码难题

题目描述 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

详见试题

!!!!!!!!:在对着别人的程序编就剁手!!!!!
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 using namespace std;
  5 int c[9]={1,1,2,6,24,120,720,5040,40320};
  6 char mb[9]={1,2,3,8,0,4,7,6,5};
  7 int dict2[4]={0,0,1,-1},
  8     dict1[4]={-1,1,0,0};
  9 bool used[400000],sign;
 10 int www;
 11 int step[400000];
 12 char  q[400000][9];
 13 int steps; 
 14 int hash(char str[9])
 15 {
 16     int i,j,k;
 17     int f[10];
 18     int sum=0;
 19     memset(f,0,sizeof(f));
 20     for (i=0;i<9;i++)
 21     {
 22         k=0;
 23         for (j=0;j<8;j++)
 24             if (j<str[i] && !f[j])
 25                 k++;
 26         f[str[i]]=1;
 27         sum+=k*c[8-i];
 28     }            
 29     return sum;
 30 }
 31 void bfs()
 32 {
 33     int i,j,h,t;
 34     int x1,y1,z1,cx,cy,cz;
 35     memset(used,0,sizeof(used));
 36     memset(step,0,sizeof(step));
 37     www=hash(q[0]);
 38     used[www]=1;
 39     h=0;
 40     t=1;
 41     while (h<t)
 42     {
 43         sign=0;
 44         for (i=0;i<9;i++)
 45         if (q[h][i]!=mb[i])
 46         {
 47             sign=1;
 48             break;
 49         }
 50         
 51         if (!sign)
 52         {
 53             steps=step[h];
 54             return;
 55         }
 56         
 57         for (i=0;i<9;i++)
 58             if (q[h][i]==0)
 59             {
 60                 x1=i/3;
 61                 y1=i%3;
 62                 z1=i;
 63                 break;
 64             }
 65         for (i=0;i<4;i++)
 66         {
 67             cx=x1+dict1[i];
 68             cy=y1+dict2[i];
 69             cz=cx*3+cy;
 70             if ((cx>=0) && (cx<3) && (cy>=0) && (cy<3))
 71             {
 72                 for (j=0;j<9;j++)
 73                     q[t][j]=q[h][j];
 74                 q[t][z1]=q[h][cz];
 75                 q[t][cz]=0;
 76                 www=hash(q[t]);
 77                 if (!used[www])
 78                 {
 79                     used[www]=1;
 80                     step[t]=step[h]+1;
 81                     t++;
 82                 }
 83             }
 84         }
 85         h++;
 86     }
 87     steps=-1;
 88     return;
 89 }
 90 int main()
 91 { 
 92     int i;
 93     char in[10];
 94     scanf("%s",in);
 95     for (i=0;i<9;i++)
 96         q[0][i]=in[i]-'1'+1;
 97     bfs();
 98     printf("%d",steps);
 99     return 0;
100 }
—Anime Otaku Save The World.
原文地址:https://www.cnblogs.com/DMoon/p/4928622.html