传送门
https://www.luogu.org/problemnew/show/P1379
思路
- 把每一个状态(如123804765)看作一个字符串,然后用Hash得到一个与之对应的数,开个vector存一下
/* 这里用到的vector用法有1. 遍历for(int i=0,siz=Hash[a].size();i<siz;i++) 2. 插入hash[a].push_back(b); */ - 然后用移动0,当作决策进行bfs,发现与目标相同的状态就ok了
Hash
** 单独把这里摘出来,这里用了两个模数,用v当链头,v2当作下标 **
int getHash(int u)
{
int v=0,v2=0;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
{
v=((ll)v*p+a[u][i][j])%mode1;
v2=((ll)v2*p+a[u][i][j])%mode2;
}
if(v==ansv&&v2==ansv2) return 2;
for(int i=0,size=Hash[v].size();i<size;i++)
if(Hash[v][i]==v2) return 1;
Hash[v].push_back(v2);
return 0;
}
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<ctime>
#include<vector>
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const int p=13;
const int mode1=1e6+7;
const int mode2=11229331;
const int N=1e6+10;
int a[N][4][4];
char s[4][4];
int xx[4]={1,0,-1,0};
int yy[4]={0,1,0,-1};
int ansv,ansv2,start_x,start_y;
int x[N],y[N],t[N];
vector <int> Hash[mode1+10];
int getHash(int u)
{
int v=0,v2=0;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
{
v=((ll)v*p+a[u][i][j])%mode1;
v2=((ll)v2*p+a[u][i][j])%mode2;
}
if(v==ansv&&v2==ansv2) return 2;
for(int i=0,size=Hash[v].size();i<size;i++)
if(Hash[v][i]==v2) return 1;
Hash[v].push_back(v2);
return 0;
}
void bfs()
{
int v=0,v2=0,head=1,tail=1;
x[1]=start_x;y[1]=start_y;t[1]=0;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
{
v=((ll)v*p+a[1][i][j])%mode1;
v2=((ll)v2*p+a[1][i][j])%mode2;
}
if(v==ansv&&v2==ansv2) {cout<<"0"<<endl;return ;}
while(head<=tail)
{
int nx=x[head],ny=y[head],nt=t[head];
for(int i=0;i<4;i++)
{
int cx=nx+xx[i],cy=ny+yy[i];
if(cx>0&&cx<4&&cy>0&&cy<4)
{
swap(a[head][nx][ny],a[head][cx][cy]);
int q=getHash(head);
if(q==2){cout<<nt+1<<endl;return ;}
else if(q==1){swap(a[head][nx][ny],a[head][cx][cy]);continue;}
else
{
tail++;
x[tail]=cx;
y[tail]=cy;
t[tail]=nt+1;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
a[tail][i][j]=a[head][i][j];
swap(a[head][nx][ny],a[head][cx][cy]);
}
}
}
head++;
}
}
int main()
{
a[0][1][1]=1;a[0][1][2]=2;a[0][1][3]=3;
a[0][2][1]=8;a[0][2][2]=0;a[0][2][3]=4;
a[0][3][1]=7;a[0][3][2]=6;a[0][3][3]=5;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
{
ansv=((ll)ansv*p+a[0][i][j])%mode1;
ansv2=((ll)ansv2*p+a[0][i][j])%mode2;
}
for(int i=1;i<=3;i++)
{
for(int j=1;j<=3;j++)
{
cin>>s[i][j];
a[1][i][j]=s[i][j]-'0';
if(a[1][i][j]==0)
{
start_x=i;
start_y=j;
}
}
}
bfs();
return 0;
}