在一个 2 x 3 的板上(board)有 5 块砖瓦,用数字 1~5 来表示, 以及一块空缺用 0 来表示.
一次移动定义为选择 0 与一个相邻的数字(上下左右)进行交换.
最终当板 board 的结果是 [[1,2,3],[4,5,0]] 谜板被解开。
给出一个谜板的初始状态,返回最少可以通过多少次移动解开谜板,如果不能解开谜板,则返回 -1 。
我的代码 8ms
class Solution {
public:
int mod=1e9+7;
struct node
{
int board[2][3];
int t,x,y;
};
int calculate_hash(node &n1)
{
int has=0;
for(int i=0;i<2;i++)
for(int j=0;j<3;j++)
{
has*=5;
has+=n1.board[i][j];
has%=mod;
}
return has;
}
int slidingPuzzle(vector<vector<int>>& board) {
int result;
node n1,n3;
int direct[4][2]={
{0,1},{0,-1},{1,0},{-1,0}};
int b[2][3]={
{1,2,3},{4,5,0}};
queue<node>que;
unordered_set<int> s;
int goal_hash=0;
bool isok=false;
for(int i=0;i<2;i++)
for(int j=0;j<3;j++)
{
n3.board[i][j]=b[i][j];
n1.board[i][j]=board[i][j];
if(board[i][j]==0)
{
n1.x=i;n1.y=j;
}
}
n1.t=0;
goal_hash=calculate_hash(n3);
int h1=calculate_hash(n1);
if(h1==goal_hash) return 0;
s.insert(h1);
que.push(n1);
while(!que.empty())
{
node n2=que.front();
que.pop();
for(int i=0;i<4;i++)
{
node temp=n2;
int t_x=temp.x+direct[i][0];
int t_y=temp.y+direct[i][1];
if(0<=t_x&&t_x<2&&0<=t_y&&t_y<3)
{
swap(temp.board[temp.x][temp.y],temp.board[t_x][t_y]);
temp.x=t_x;
temp.y=t_y;
temp.t=n2.t+1;
int temp_hash=calculate_hash(temp);
if(temp_hash==goal_hash)
{
isok=true;
result=temp.t;
break;
}
else if(s.count(temp_hash)==0)
{
s.insert(temp_hash);
que.push(temp);
}
else
continue;
}
}
if(isok) break;
}
if(!isok) result=-1;
return result;
}
};