noj 算法 八数码问题
描述
在九宫格里放在1到8共8个数字还有一个是空格,与空格相邻的数字可以移动到空格的位置,问给定的状态最少需要几步能到达目标状态(用0表示空格):
1 2 3
4 5 6
7 8 0
1 2 3
4 5 6
7 8 0
输入
输入一个给定的状态。
输出
输出到达目标状态的最小步数。不能到达时输出-1。
输入样例
1 2 3
4 0 6
7 5 8
4 0 6
7 5 8
输出样例
2
代码:
#include <iostream> #include <stdio.h> #include<queue> #include<map> using namespace std; int a[3][3]; queue<int>q; int dir[4][2]={-1,0,0,1,1,0,0,-1}; int r,c; map<int,int>visited; map<int,int>step; int canmove(int u,int d) { for(int i=2;i>=0;i--){ for(int j=2;j>=0;j--){ a[i][j]=u%10; u/=10; if(a[i][j]==0){ r=i; c=j; } } } if((d==0&&r==0)||(d==1&&c==2)||(d==2&&r==2)||(d==3&&c==0)) return 0; return 1; } int moveto(int u,int d) { int t=0; int nr=r+dir[d][0]; int nc=c+dir[d][1]; a[r][c]=a[nr][nc]; a[nr][nc]=0; for(int i=0;i<3;i++) for(int j=0;j<=2;j++) { t=t*10+a[i][j]; } return t; } int bfs(int n) { q.push(n); visited[n]=1; step[n]=0; while(!q.empty()) { int u=q.front(); q.pop(); if(u==123456780) return step[u]; for(int i=0;i<4;i++) { if(canmove(u,i)) { int v=moveto(u,i); if(!visited[v]) { visited[v]=1; step[v]=step[u]+1; q.push(v); } } } } return -1; } int main() { int i,j,n=0; for(i=0;i<3;i++){ for(j=0;j<3;j++){ cin>>a[i][j]; n=n*10+a[i][j]; } } int sum=bfs(n); cout<<sum<<endl; return 0; }