我的天!!这道题看刘汝佳的书首先就看不懂,之后上网找解题报告也看不懂,主要是以为哈希技术不知道
后来问了一下凯哥根据自己的理解勉强AC出来了
哈希技术 简略点就是将 用一个哈希函数将一个很大的数据分成好几份,并且每组数据利用链接进行遍历
哈希函数的构造一般用一个很大的素数
int hash(int ss[9]){
int sum=0;
for(int i=0;i<9;i++)
sum=sum*10+ss[i];
return sum%MAX_SIZE;
}
bool Try_to_insert(int s){
int h=hash(State[s]);
int u=head[h];
while(u){
if(memcmp(State[u],State[s],sizeof(State[s]))==0)
return false;
u=next[u];
}
next[s]=head[h];
head[h]=s;
return true;
}
head[h]就代表所有经过哈希函数求解之后得到的值为h的数的集合的链节头
next[s]为s的下一个元素是什么
我的天总之这题做的水的很,还有很多搞不懂的地方
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define MAXD 5
#define MAX_SIZE 1000003
const int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
const char dirs[]="UDLR";/*上、右、下、左*/
int State[MAX_SIZE][9];
char Str[MAX_SIZE][100];
int dist[MAX_SIZE];
int head[MAX_SIZE];
int next[MAX_SIZE];
int front;
int back;
int hash(int ss[9]){
int sum=0;
for(int i=0;i<9;i++)
sum=sum*10+ss[i];
return sum%MAX_SIZE;
}
bool Try_to_insert(int s){
int h=hash(State[s]);
int u=head[h];
while(u){
if(memcmp(State[u],State[s],sizeof(State[s]))==0)
return false;
u=next[u];
}
next[s]=head[h];
head[h]=s;
return true;
}
void display(int mat[][4]){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++)
printf("%d ",mat[i][j]);
printf("\n");
}
}
void solve(){
front = 1;
back = 2;
while(front<back){
int temp[4][4];
int x,y;
for(int i=0,k=0;i<3;i++)
for(int j=0;j<3;j++,k++){
temp[i][j]=State[front][k];
if(temp[i][j]==0){
x=i;y=j;/*记录为0的点*/
}
}
/*先转化为2维数组*/
for(int i=0;i<4;i++){
int st[4][4];
int nx=x+dir[i][0];
int ny=y+dir[i][1];
memcpy(st,temp,sizeof(st));
if(nx>=0&&ny>=0&&nx<3&&ny<3){
st[x][y] = st[nx][ny];
st[nx][ny] = 0;
/*交换块的位置*/
for(int z=0,k=0;z<3;z++)
for(int j=0;j<3;j++,k++)
State[back][k]=st[z][j];
int z;
for(z=0;z<strlen(Str[front]);z++){
Str[back][z]=Str[front][z];
}
Str[back][z]=dirs[i];
Str[back][z+1]='\0';
if(Try_to_insert(back))
back++;
}
}
front++;
}
}
int main(){
int N;
scanf("%d",&N);
for(int cases=1;cases<=N;cases++){
memset(head,0,sizeof(head));
memset(next,0,sizeof(next));
memset(dist,0,sizeof(dist));
memset(State,0,sizeof(State));
memset(Str,0,sizeof(Str));
for(int i=0;i<9;i++)
scanf("%d",&State[1][i]);
Str[1][0]='\0';
solve();
printf("Puzzle #%d\n",cases);
for(int i=0;i<9;i++){
printf("%d",State[back-1][i]);
if((i+1)%3==0)
printf("\n");
else
printf(" ");
}
puts(Str[back-1]);
printf("\n");
}
return 0;
}