考虑用广度优先搜索。
广度优先主要需要解决的问题是如何存储状态,如何判断当前状态是否在以前出现过。
每个状态由四个数字组成,从1111 -- 9999 用一个四个下标(四维)的数组(s[9][9][9][9])存储,对应的值表示状态是否出现过,这样一来判重就变的十分简单。
还需要一个队列(数组q[9*9*9*9])来记录需要扩展的状态,pf与pe为队头和队尾。
每次扩展共有7(4+4+3)种情况,将其一一列出即可。
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#define swap(a,b) {a=a^b;b=b^a;a=a^b;}
char s[9][9][9][9 ];
int q[9*9*9*9 ],pe,pf;
int steps;
int from,to;
void copy(char from[4],char to[4 ])
... {
int i;
for(i = 0; i < 4; i++)
to[i] = from[i];
}
void bfs()
... {
int i,k,flag = 0;
char a[4],b[4];
k = from;
q[pe++] = k;
while(1)
...{
k = q[pf++];
for(i = 0; i < 4; i++)
...{
a[i] = k % 10;
k / = 10;
}
for(i = 0; i < 3; i++)
...{
copy(a,b);
if(b[i] == b[i + 1])
continue;
swap(b[i],b[i + 1]);
k = b[0] + 10 * b[1] + 100 * b[2] + 1000 * b[3];
if(k == to)
return;
if(s[b[0] - 1][b[1] - 1][b[2] - 1][b[3] - 1] == 0)
...{
q[pe++] = k;
s[b[0] - 1][b[1] - 1][b[2] - 1][b[3] - 1] = 1;
}
}
for(i = 0; i < 4; i++)
...{
copy(a,b);
if(b[i] < 9)
b[i]++;
else
b[i] = 1;
k = b[0] + 10 * b[1] + 100 * b[2] + 1000 * b[3];
if(k == to)
return;
if(s[b[0] - 1][b[1] - 1][b[2] - 1][b[3] - 1] == 0)
...{
q[pe++] = k;
s[b[0] - 1][b[1] - 1][b[2] - 1][b[3] - 1] = 1;
}
copy(a,b);
if(b[i] > 1)
b[i]--;
else
b[i] = 9;
k = b[0] + 10 * b[1] + 100 * b[2] + 1000 * b[3];
if(k == to)
return;
if(s[b[0] - 1][b[1] - 1][b[2] - 1][b[3] - 1] == 0)
...{
q[pe++] = k;
s[b[0] - 1][b[1] - 1][b[2] - 1][b[3] - 1] = 1;
}
}
if(pf >= flag)
...{
flag = pe;
steps++;
}
}
}
void solve()
... {
scanf("%d",&from);
scanf("%d",&to);
if(from == to)
...{
printf("0 ");
return;
}
pe = pf = 0;
steps = 0;
memset(s,0,sizeof(char)*9*9*9*9);
memset(q,0,sizeof(int)*9*9*9*9);
bfs();
printf("%d ",++steps);
}
void main()
... {
int t;
#ifndef ONLINE_JUDGE
freopen("test.txt","r",stdin);
#endif
while(scanf("%d",&t)!=EOF)
while(t--)
solve();
#ifndef ONLINE_JUDGE
fclose(stdin);
#endif
}
#include<string.h>
#define swap(a,b) {a=a^b;b=b^a;a=a^b;}
char s[9][9][9][9 ];
int q[9*9*9*9 ],pe,pf;
int steps;
int from,to;
void copy(char from[4],char to[4 ])
... {
int i;
for(i = 0; i < 4; i++)
to[i] = from[i];
}
void bfs()
... {
int i,k,flag = 0;
char a[4],b[4];
k = from;
q[pe++] = k;
while(1)
...{
k = q[pf++];
for(i = 0; i < 4; i++)
...{
a[i] = k % 10;
k / = 10;
}
for(i = 0; i < 3; i++)
...{
copy(a,b);
if(b[i] == b[i + 1])
continue;
swap(b[i],b[i + 1]);
k = b[0] + 10 * b[1] + 100 * b[2] + 1000 * b[3];
if(k == to)
return;
if(s[b[0] - 1][b[1] - 1][b[2] - 1][b[3] - 1] == 0)
...{
q[pe++] = k;
s[b[0] - 1][b[1] - 1][b[2] - 1][b[3] - 1] = 1;
}
}
for(i = 0; i < 4; i++)
...{
copy(a,b);
if(b[i] < 9)
b[i]++;
else
b[i] = 1;
k = b[0] + 10 * b[1] + 100 * b[2] + 1000 * b[3];
if(k == to)
return;
if(s[b[0] - 1][b[1] - 1][b[2] - 1][b[3] - 1] == 0)
...{
q[pe++] = k;
s[b[0] - 1][b[1] - 1][b[2] - 1][b[3] - 1] = 1;
}
copy(a,b);
if(b[i] > 1)
b[i]--;
else
b[i] = 9;
k = b[0] + 10 * b[1] + 100 * b[2] + 1000 * b[3];
if(k == to)
return;
if(s[b[0] - 1][b[1] - 1][b[2] - 1][b[3] - 1] == 0)
...{
q[pe++] = k;
s[b[0] - 1][b[1] - 1][b[2] - 1][b[3] - 1] = 1;
}
}
if(pf >= flag)
...{
flag = pe;
steps++;
}
}
}
void solve()
... {
scanf("%d",&from);
scanf("%d",&to);
if(from == to)
...{
printf("0 ");
return;
}
pe = pf = 0;
steps = 0;
memset(s,0,sizeof(char)*9*9*9*9);
memset(q,0,sizeof(int)*9*9*9*9);
bfs();
printf("%d ",++steps);
}
void main()
... {
int t;
#ifndef ONLINE_JUDGE
freopen("test.txt","r",stdin);
#endif
while(scanf("%d",&t)!=EOF)
while(t--)
solve();
#ifndef ONLINE_JUDGE
fclose(stdin);
#endif
}