「LuoguP1379」 八数码难题(迭代加深

【P1379】八数码难题 - 洛谷

题目描述

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

输入输出格式

输入格式:

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

输出格式:

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

输入输出样例

输入样例#1: 复制
283104765
输出样例#1: 复制
4

题解

当迭代加深练手题做的。

这题叭也没什么好讲的,就是搜哇搜哇就行啦

 1 /*
 2     qwerta
 3     P1379 八数码难题
 4     Accepted
 5     100
 6     代码 C++,1.06KB
 7     提交时间 2018-10-01 21:50:56
 8     耗时/内存
 9     2106ms, 816KB
10 */
11 /*
12 这中间的状态记录把九宫格如下编号:
13 1 2 3
14 4 5 6
15 7 8 9
16 */
17 #include<iostream>
18 #include<cstdlib>
19 #include<cstdio>
20 using namespace std;
21 #define LL long long
22 int dep;//限制深度
23 int a[13];//把状态拆开之后放这儿
24 int chai(int x)//拆!
25 {
26     int ret;//记一下0在哪儿
27     for(register int i=9;i>=1;--i)
28     {
29         if(x%10==0)ret=i;
30         a[i]=x%10;
31         x/=10;
32     }
33     return ret;
34 }
35 LL ans=123804765;//目标态
36 LL sub()//把拆开的压起来
37 {
38     LL x=0;
39     for(register int i=1;i<=9;++i)
40     x=x*10+a[i];
41     return x;
42 }
43 void dfs(int k,int d,int bef)// k:0在哪儿 d:当前深度 bef:上一次的操作
44 {
45     if(sub()==ans){cout<<d-1;exit(0);}//找到了就输出
46     if(d>dep)return;//超过限定深度啦
47     //mvup 把空格往上移
48     if(k>3&&bef!=1){swap(a[k-3],a[k]);dfs(k-3,d+1,3);swap(a[k-3],a[k]);}
49     //mvdown 把空格往下
50     if(k<7&&bef!=3){swap(a[k+3],a[k]);dfs(k+3,d+1,1);swap(a[k+3],a[k]);}
51     //mvleft 往左
52     if(k%3!=1&&bef!=2){swap(a[k-1],a[k]);dfs(k-1,d+1,4);swap(a[k-1],a[k]);}
53     //mvright 往右
54     if(k%3!=0&&bef!=4){swap(a[k+1],a[k]);dfs(k+1,d+1,2);swap(a[k+1],a[k]);}
55 }
56 int main()
57 {
58     //freopen("a.in","r",stdin);
59     LL x;
60     cin>>x;
61     dep=0;
62     while(1)
63     {
64         ++dep;//迭代加深
65         int k=chai(x);
66         dfs(k,1,0);
67     }
68     return 0;
69 }
原文地址:https://www.cnblogs.com/qwerta/p/9738130.html