洛谷 P1379 八数码难题
题目描述
在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。
输入输出格式
输入格式:输入初始状态,一行九个数字,空格用0表示
输出格式:
只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)
输入输出样例
输入样例#1:
283104765
输出样例#1:
4
思路:
另一个:http://blog.csdn.net/largecub233/article/details/65096062
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int ans,num[4][4]; int n,m,x,y,z,X,Y; int dx[4]={0,1,-1,0}; int dy[4]={1,0,0,-1}; int fx[11]={0,1,1,1,2,3,3,3,2}; int fy[11]={0,1,2,3,3,3,2,1,1}; int H(){ int bns=0; for(int i=1;i<=3;i++) for(int j=1;j<=3;j++) if(num[i][j]) bns+=abs(i-fx[num[i][j]])+abs(j-fy[num[i][j]]); return bns; } void dfs(int k,int X,int Y,int g){ int h=H(); if(!h){ ans=g; return ; } if(h+g>k||ans||g==k) return ; for(int i=0;i<4;i++){ int x=dx[i]+X; int y=dy[i]+Y; if(x>=1&&y>=1&&x<=3&&y<=3){ swap(num[X][Y],num[x][y]); dfs(k,x,y,g+1); swap(num[x][y],num[X][Y]); } } } int main(){ for(int i=1;i<=3;i++) for(int j=1;j<=3;j++){ char x; scanf("%c",&x); num[i][j]=x-'0'; if(!num[i][j]) X=i,Y=j; } for(int k=0;;k++){ dfs(k,X,Y,0); if(ans){ printf("%d",ans); return 0; } } }
细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。
雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。