题目描述
初始状态的步数就算1,哈哈
输入:第一个3*3的矩阵是原始状态,第二个3*3的矩阵是目标状态。
输出:移动所用最少的步数
Input
2 8 3
1 6 4
7 0 5
1 2 3
8 0 4
7 6 5
Output
6
分析:题目意思是,值为0的点可以在3*3的网格内,向上、下、左、右四个方向移动,每次移动和原来在该格子上的值进行交换。可以将3*3的矩阵转化为一个9位的数字进行存储,用map记录这个数字是否出现过。从初始状态开始BFS,一直找到目标状态为止。
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <cstdio>
#include <queue>
#include <stack>
#include <ctime>
#include <cmath>
#include <map>
#include <set>
#include<unordered_map>
#define INF 0x3f3f3f3f
#define db1(x) cout<<#x<<"="<<(x)<<endl
#define db2(x,y) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<endl
#define db3(x,y,z) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<", "<<#z<<"="<<(z)<<endl
#define db4(x,y,z,a) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<", "<<#z<<"="<<(z)<<", "<<#a<<"="<<(a)<<endl
#define db5(x,y,z,a,r) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<", "<<#z<<"="<<(z)<<", "<<#a<<"="<<(a)<<", "<<#r<<"="<<(r)<<endl
using namespace std;
typedef struct node
{
int x,y;
}node;
typedef struct pos
{
long long num;
int t;
}pos;
int main(void)
{
#ifdef test
freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
clock_t start=clock();
#endif //test
int f=0,ans=0;
int dir_x[]={0,0,-1,1};
int dir_y[]={-1,1,0,0};
long long ini[3][3],fin[3][3];
long long cnt_fin=0,cnt_now=0;
for(int i=0;i<3;++i)
for(int j=0;j<3;++j)
scanf("%lld",&ini[i][j]),cnt_now=cnt_now*10+ini[i][j];
for(int i=0;i<3;++i)
for(int j=0;j<3;++j)
scanf("%lld",&fin[i][j]),cnt_fin=cnt_fin*10+fin[i][j];
map<long long,int>mp;
mp[cnt_now]=1;
pos now;
now.num=cnt_now,now.t=1;
queue<pos>que;que.push(now);
while(!que.empty())
{
pos temp_cnt=que.front();que.pop();
if(temp_cnt.num==cnt_fin)
{
f=1;ans=temp_cnt.t;
break;
}
temp_cnt.t++;
long long temp_ini[3][3];
node zero;
for(int i=2;i>=0;--i)
{
for(int j=2;j>=0;--j)
{
temp_ini[i][j]=temp_cnt.num%10,temp_cnt.num/=10;
if(temp_ini[i][j]==0)
zero.x=i,zero.y=j;
}
}
for(int i=0;i<4;++i)
{
node temp_pos=zero;
temp_pos.x+=dir_x[i],temp_pos.y+=dir_y[i];
if(temp_pos.x<0||temp_pos.x>2||temp_pos.y<0||temp_pos.y>2)continue;
swap(temp_ini[temp_pos.x][temp_pos.y],temp_ini[zero.x][zero.y]);
temp_cnt.num=0;
for(int j=0;j<3;++j)
for(int k=0;k<3;++k)
temp_cnt.num=temp_cnt.num*10+temp_ini[j][k];
if(temp_cnt.num==cnt_fin)
{
f=1;ans=temp_cnt.t;
break;
}
if(mp[temp_cnt.num]!=1)
mp[temp_cnt.num]=1,que.push(temp_cnt);
swap(temp_ini[temp_pos.x][temp_pos.y],temp_ini[zero.x][zero.y]);
}
if(f==1)break;
}
if(f==1)printf("%d\n",ans);
#ifdef test
clockid_t end=clock();
double endtime=(double)(end-start)/CLOCKS_PER_SEC;
printf("\n\n\n\n\n");
cout<<"Total time:"<<endtime<<"s"<<endl; //s为单位
cout<<"Total time:"<<endtime*1000<<"ms"<<endl; //ms为单位
#endif //test
return 0;
}