【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 }