64,681
社区成员
发帖
与我相关
我的任务
分享
#include<iostream>
#include<vector>
using namespace std;
const int M=9;
const int N=3;
const int MAX=1000000;
typedef int State[M];//State类型用来存这9个数
State s[MAX],goal;
int dist[MAX];//这个用来存最短的移动距离
int fa[MAX];
const int K=4;
//左,上,右,下
int movex[K]={-1,0,1,0};//这个代表横轴上的移动距离
int movey[K]={0,-1,0,1};
const int MAXHASHSIZE=1000003;
int head[MAXHASHSIZE],next[MAXHASHSIZE];//这个是用来hash的数组
void init(){//初始化
dist[0]=0;
fa[0]=-1;
memset(head,0,sizeof(head));
}
int hash(const State& s){//求hash值
int v=0;
for(int i=0;i<M;++i)
v=v*10+s[i];
return v%MAXHASHSIZE;//取模
}
bool try_to_insert(int k){//试探可否将其加入,如果在hash表中存在返回false,否则返回true
int h=hash(s[k]);
int u=head[h];
while(u){
if(memcmp(s[k],s[u],sizeof(State))==0)return false;
u=next[u];
}
next[k]=head[h];
head[h]=k;
return true;
}
int bfs(){//广度优先搜索,运用了队列这一数据结构
int front=0,rear=1;//front表示出对端,rear表示入队端
int current_fa=0;
while(front<rear){
State &t=s[front];
if(memcmp(t,goal,sizeof(State))==0)return front;//找到目标位置返回
int i;
for(int z=0;z<M;++z)
if(t[z]==0)break;
int x=z/N,y=z%N;
int newx,newy,newz;
for(i=0;i<K;++i){//根据左,上,右,下四个方向分别试探
newx=x+movex[i];
newy=y+movey[i];
newz=newx*N+newy;
if(newx>=0&&newx<N&&newy>=0&&newy<N){//如果可以这样移动进入if语句
State &c=s[rear];
memcpy(c,t,sizeof(State));
c[newz]=t[z];
c[z]=t[newz];
dist[rear]=dist[front]+1;//更新新加入的距离
fa[rear]=front;//设置父节点,以便输出整条路径
if(try_to_insert(rear))++rear;//如果可以加入,rear加1
}
}
++front;
}
}
int main(){
{
for(int i=0;i<M;++i)//输入源9数
cin>>s[0][i];
}
{
for(int i=0;i<M;++i)//输入目标9数
cin>>goal[i];
}
init();//初始化
int ans=bfs();//获得目标位置
cout<<"steps :"<<dist[ans]<<endl;//输出最短移动距离
int f=ans;
vector<int> pos;//下面是输出整条移动方案
do{
pos.push_back(f);
f=fa[f];
}while(f!=-1);
for(int i=pos.size()-1;i>=0;--i){
State &t=s[pos[i]];
for(int j=0;j<M;++j){
cout<<t[j]<<" ";
if(j%N==2)cout<<endl;
}
cout<<endl;
}
return 0;
}
#include<iostream>
#include<vector>
using namespace std;
const int M=9;
const int N=3;
const int MAX=1000000;
typedef int State[M];
State s[MAX],goal;
int dist[MAX];
int fa[MAX];
const int K=4;
int movex[K]={-1,0,1,0};
int movey[K]={0,-1,0,1};
const int MAXHASHSIZE=1000003;
int head[MAXHASHSIZE],next[MAXHASHSIZE];
void init(){
dist[0]=0;
fa[0]=-1;
memset(head,0,sizeof(head));
}
int hash(const State& s){
int v=0;
for(int i=0;i<M;++i)
v=v*10+s[i];
return v%MAXHASHSIZE;
}
bool try_to_insert(int k){
int h=hash(s[k]);
int u=head[h];
while(u){
if(memcmp(s[k],s[u],sizeof(State))==0)return false;
u=next[u];
}
next[k]=head[h];
head[h]=k;
return true;
}
int bfs(){
int front=0,rear=1;
int current_fa=0;
while(front<rear){
State &t=s[front];
if(memcmp(t,goal,sizeof(State))==0)return front;
int i;
for(int z=0;z<M;++z)
if(t[z]==0)break;
int x=z/N,y=z%N;
int newx,newy,newz;
for(i=0;i<K;++i){
newx=x+movex[i];
newy=y+movey[i];
newz=newx*N+newy;
if(newx>=0&&newx<N&&newy>=0&&newy<N){
State &c=s[rear];
memcpy(c,t,sizeof(State));
c[newz]=t[z];
c[z]=t[newz];
dist[rear]=dist[front]+1;
fa[rear]=front;
if(try_to_insert(rear))++rear;
}
}
++front;
}
}
int main(){
{
for(int i=0;i<M;++i)
cin>>s[0][i];
}
{
for(int i=0;i<M;++i)
cin>>goal[i];
}
init();
int ans=bfs();
cout<<"steps :"<<dist[ans]<<endl;
int f=ans;
vector<int> pos;
do{
pos.push_back(f);
f=fa[f];
}while(f!=-1);
for(int i=pos.size()-1;i>=0;--i){
State &t=s[pos[i]];
for(int j=0;j<M;++j){
cout<<t[j]<<" ";
if(j%N==2)cout<<endl;
}
cout<<endl;
}
return 0;
}