8 digital problem, that is, in a 3x3 matrix has 8 numbers (1 to 8) and a space, from one state to another state, each time can only move a number adjacent to a space in the space
Aoj-417-8 Digital
http://icpc.ahu.edu.cn/OJ/Problem.aspx?id=417
This is the minimum number of steps to seek conversion, can be solved with BFS, a total of 9!=362880, the key is how to mark the status of the visited, to ensure that the status of each search is the smallest number of steps, where the string can be converted to the corresponding integer to deal with, the use of Cantor expansion to save storage space
Cantor Expand: x=an* (n-1)!+an-1* (n-2)!+...+ai* (i-1)!+...+a2*1!+a1*0!
AI is ranked in number (0<=ai<i) for numbers that do not appear in the current
For example 3 5 7 4 1 2 9 6 8 expand to
x=2*8!+3*7!+4*6!+2*5!+0*4!+0*3!+2*2!+0*1!+0*0!=98884
#include <stdio.h> #include <string.h> #include <stdlib.h> char a[363000][9];
A total of 9!=362880, with char storage space-saving char goal[9];
Char visit[363000];
int dis[363000];
int dir[4][2]={{-1,0},{1,0},{0,1},{0,-1}};
int c[9]={1,1,2,6,24,120,720,5040,40320};
int find (char str[9])//Converts the string to an integer {int i,j,k;
int f[10];
int sum=0;
memset (F,0,sizeof (f));
for (i=0;i<9;i++) {k=0;
for (j=0;j<8;j++) if (j<str[i]&&!f[j]) k++;
F[str[i]]=1;
Sum+=k*c[8-i];
} return sum;
} int BFs () {int i,j,t,flag;
int head,tail;
int x, y, Z;
int nx,ny,nz; memset (dis,0,sizeof (dis)); The number of small steps to each state memset (visit,0,sizeof (visit));
The marked points cannot be repeated t=find (a[0]);
Visit[t]=1;
Head=0;
tail=1;
while (Head<tail) {flag=1;
for (i=0;i<9;i++) if (A[head][i]!=goal[i])//And the target State is the same as stop searching {flag=0;
Break
} if (flag) return Dis[head];
for (i=0;i<9;i++)//Find 0 where if (a[head][i]==0) {X=I/3;
y=i%3;
Z=i;
Break } foR (i=0;i<4;i++) {nx=x+dir[i][0];
NY=Y+DIR[I][1];
Nz=nx*3+ny;
if (0<=nx&&nx<3&&0<=ny&&ny<3) {for (j=0;j<9;j++) a[tail][j]=a[head][j]; A[TAIL][Z]=A[HEAD][NZ];
Make a move, i.e. not 0 elements and 0 Exchange a[tail][nz]=0;
T=find (A[tail]);
if (!visit[t]) {visit[t]=1;
dis[tail]=dis[head]+1;
tail++;
}}} head++;
} return-1;
} int main () {int i,ans;
for (i=0;i<9;i++) scanf ("%d", &a[0][i]);
for (i=0;i<9;i++) scanf ("%d", &goal[i]);
Ans=bfs ();
if (ans==-1) printf ("impossible\n");
else printf ("%d\n", ans);
return 0;
}
Poj-1077-eight
http://poj.org/problem?id=1077
This question does not need to require the minimum number of steps, the need to move the road, and the same as above, with BFS, and then record the road strength, the final reverse output can be
#include <stdio.h> #include <string.h> #include <stdlib.h> char a[363000][9];
A total of 9!=362880, with char storage space-saving char goal[9];
Char visit[363000];
int dis[363000]; int step[363000]; From the previous step to the direction of int pre[363000];
status int Dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}} from the previous step;
Char name[4]={' d ', ' U ', ' R ', ' L '};
int c[9]={1,1,2,6,24,120,720,5040,40320};
void init () {int i;
for (i=0;i<8;i++) goal[i]=i+1;
goal[8]=0;
} int Find (char str[9])//Convert the string to an integer {int i,j,k;
int f[10];
int sum=0;
memset (F,0,sizeof (f));
for (i=0;i<9;i++) {k=0;
for (j=0;j<8;j++) if (j<str[i]&&!f[j]) k++;
F[str[i]]=1;
Sum+=k*c[8-i];
} return sum;
} int BFs () {int i,j,t,flag;
int head,tail;
int p,q,temp;
int x, y, Z;
int nx,ny,nz;
Char sol[5000]; memset (dis,0,sizeof (dis)); The number of small steps to each state memset (visit,0,sizeof (visit));
The marked points cannot be repeated memset (step,0,sizeof (step));
T=find (A[0]);
Visit[t]=1;
Step[0]=pre[0]=-1;
Head=0;
tail=1;
while (Head<tail){flag=1;
for (i=0;i<9;i++) if (A[head][i]!=goal[i])//And the target State is the same as stop searching {flag=0;
Break
} if (flag)//print path strength {temp=0; while (head) {P=pre[head]; The state of the previous step Q=step[head];
From the direction of the previous step sol[temp++]=name[q];
Head=p;
} for (i=temp-1;i>=0;i--) printf ("%c", Sol[i]);
printf ("\ n");
return 1;
} for (i=0;i<9;i++)//Find 0 where if (a[head][i]==0) {X=I/3;
y=i%3;
Z=i;
Break } for (i=0;i<4;i++) {nx=x+dir[i][0];
Move 0 elements Ny=y+dir[i][1];
Nz=nx*3+ny;
if (0<=nx&&nx<3&&0<=ny&&ny<3) {for (j=0;j<9;j++) a[tail][j]=a[head][j]; A[TAIL][Z]=A[HEAD][NZ];
Make a move, i.e. not 0 elements and 0 Exchange a[tail][nz]=0;
T=find (A[tail]);
if (!visit[t]) {visit[t]=1;
dis[tail]=dis[head]+1; Pre[tail]=head; The state step[tail]=i from the previous step;
tail++ from the direction of the previous step;
}}} head++;
} return-1;
} int main () {int i,k,ans;
Char ss[50]; k=0;
Gets (ss);
For (I=0;i<strlen (ss); i++) {if (' 0 ' <=ss[i]&&ss[i]<= ' 9 ') a[0][k++]= (ss[i]-' 0 ');
else if (ss[i]== ' x ') a[0][k++]=0;
} init ();
Ans=bfs ();
if (ans==-1) printf ("unsolvable\n");
return 0;
}