the reason of failure:1、如何对0进行上下左右移动
用pos找到0在数组中的下标
可以定义dr[]={0,1,0,-1};dc[]={1,0,-1,0}.然后一个for4次的循环,r=pos/3+dr c=pos%3+dc
便能实现上下左右的移动
2、对于储存状态与查找,可以把数组存入set然后查找。
题意
八数码问题。编号为1~8的8个正方形滑块被摆成3行3列(有一个格子留空),如图7-
14所示。每次可以把与空格相邻的滑块(有公共边才算相邻)移到空格中,而它原来的位置
就成为了新的空格。给定初始局面和目标局面(用0表示空格),你的任务是计算出最少的
移动步数。如果无法到达目标局面,则输出-1。
图7-14 八数码问题举例
代码:
#include <iostream>
#include <queue>
#include <string.h>
#include <set>
using namespace std;
struct ttt{
int t;
int a[9];
};
int str2[9];
int dr[]={1,0,-1,0};
int dc[]={0,1,0,-1};
int main(){
set<int>vis;
freopen("in.txt","r",stdin);
queue<ttt>qq;
int n,r,c;
int i,j,k,l,pos1,t1;
ttt str1,str4,str3;
cin >> n;
for(i=0;i<n;i++){
for(j=0;j<9;j++)
cin >> str1.a[j];
for(j=0;j<9;j++)
cin >> str2[j];
str1.t=0;
qq.push(str1);
int t1=0;
while(!qq.empty()){
t1++;
str3=qq.front();qq.pop();
if(memcmp(str3.a,str2,sizeof(str2))==0){
break;}
for(j=0;j<9;j++){
if(str3.a[j]==0){
pos1=j;
break;
}
}
str3.t++;
for(j=0;j<4;j++){
r=pos1/3+dr[j];
c=pos1%3+dc[j];
memcpy(&str4,&str3,sizeof(str3));
if(r>=0&&r<3&&c<3&&c>=0){
str4.a[pos1]=str3.a[r*3+c];
str4.a[r*3+c]=0;
int g=0;
for(k=0;k<9;k++){
g=g*10+str4.a[k];
}
// cout << g << endl;
if(!vis.count(g)){
vis.insert(g);
qq.push(str4);}
}
}
}
if(memcmp(str3.a,str2,sizeof(str2))==0)
cout << str3.t << endl;
else
cout << "-1" << endl;
}
return 0;
}
2、用hash判重。
the reason of failure :1、hash需要把所有值都放入st[]这样一个大数组中才能找到之前是否存在里面,hash的mod尽量找一个大的素数。
2、关于memcmp与memcpy都是需要sizeof(a)写大小的。
代码:
#include <iostream>
#include <queue>
#include <string.h>
using namespace std;
struct ttt{
int a[9],t;
};
const int hashsize =1000003;
typedef int con[9];
int head[5000000];
int next[5000000];
con st[50000000];
int dr[]={0,1,-1,0};
int dc[]={1,0,0,-1};
int aa;
ttt str1,str3,str4;
int str2[9];
int hash(con str5){
int t1=0;
for(int g=0;g<9;g++)t1=t1*10+str5[g];
// cout << "t1=" << t1 << endl;
return t1%hashsize;
}
int try_insert(int s){
int h=hash(st[s]);
int u=head[h];
while(u){
if(memcmp(st[u],st[s],sizeof(st[s]))==0)return 0;
u=next[u];
}
head[h]=s;
next[s]=u;
return 1;
}
int main(){
memset(head,0,sizeof(head));
freopen("in.txt","r",stdin);
queue<ttt>qq;
int i,j,k,l;
int r,c,pos1;
long long g=1;
for(i=0;i<9;i++)
cin >> str1.a[i];
for(i=0;i<9;i++)
cin >> str2[i];
str1.t=0;
qq.push(str1);
while(!qq.empty()){
str3=qq.front();
qq.pop();
if(memcmp(str3.a,str2,sizeof(str2))==0)break;
for(i=0;i<9;i++){
if(str3.a[i]==0){
pos1=i;
break;}
}
str3.t++;
for(i=0;i<4;i++){
r=pos1/3+dr[i];
c=pos1%3+dc[i];
if(r>=0&&r<3&&c>=0&&c<3){
str4=str3;
str4.a[pos1]=str3.a[r*3+c];
str4.a[r*3+c]=0;
memcpy(st[g],str4.a,sizeof(st[g]));
if(try_insert(g)){
qq.push(str4);
g++;
}
}
}
}
if(memcmp(str3.a,str2,sizeof(str2))==0)
cout << str3.t << endl;
else
cout << "-1" << endl;
return 0;
}