1225 八数码难题

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

详见试题

 1 #include<iostream>
 2 #include<cstdio>
 3 #define N 500000
 4 using namespace std;
 5 int step[N];
 6 struct node{
 7     int map[4][4];
 8 }a[N];
 9 int yd[4] = {0,0,1,-1};
10 int yyd[4] = {1,-1,0,0};
11 int g[4][4]={{0,0,0,0},{0,1,2,3},{0,8,0,4},{0,7,6,5}};
12 int ha[3733800];
13 int h=0;
14 int t=1;
15 int flag;
16 bool pd(int x,int y)//判断不越界 
17 {
18     if(x>=1&&x<=3&&y>=1&&y<=3)
19      return 1;
20      return 0;
21 }
22 bool bj()//将移动后的新矩阵与目标矩阵进行对比 
23 {
24     for(int i=1;i<=3;i++)
25          for(int j=1;j<=3;j++)
26               if(a[t].map[i][j]!=g[i][j])
27                    return 0;
28      return 1;
29 }
30 bool HA()//判断已经出现过 
31 {
32     int s=0;
33     int k=1;
34     for(int i=1;i<=3;i++)
35      {
36          for(int j=1;j<=3;j++)
37           {
38               s+=a[t].map[i][j]*k;
39               k*=8;
40           }
41      }
42      s%=3733799;
43      if(ha[s]==0)
44       {
45           ha[s]=1;
46           return 1;
47       } 
48           return 0;
49 }
50 void move(int x,int y)//核心,移动 
51 {
52     for(int i=0;i<4;i++)
53      {
54          int q=x+yd[i],p=y+yyd[i];//每一种情况 
55          if(pd(q,p)==1)
56           {
57               for(int j=1;j<=3;j++)
58                    for(int k=1;k<=3;k++)
59                         a[t].map[j][k]=a[h].map[j][k];
60                swap(a[t].map[x][y],a[t].map[q][p]);
61                step[t]=step[h]+1;
62                if(bj())
63                {
64                    cout<<step[t];
65                    flag=1;
66                    return ;
67                }
68                if(HA()==1)
69                 {
70                     t++;
71                 }
72           }
73      }
74 }
75 void search()//将栈不断进行操作到h=t结束 
76 {
77     while(h<t)
78     {
79         for(int i=1;i<=3;i++)       
80              for(int j=1;j<=3;j++)
81               {
82                 if(a[h].map[i][j]==0)
83                      move(i,j);//从0,0开始移动 
84                 if(flag==1)
85                      return ;     
86            }
87        h++;//tou++ 
88     }
89     
90 }
91 int main()//将其用string类型输入 
92 {
93     string s;
94     cin>>s;
95     for(int i=1;i<=3;i++)
96          for(int j=1;j<=3;j++)
97               a[0].map[i][j]=s[(i-1)*3+j-1]-'0';//存入a.map数组 
98      search();//
99 }

 

转载于:https://www.cnblogs.com/lyqlyq/p/6749902.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值