题目描述
小明忘记了旅行箱上的密码,现在他想自己暴力弄出密码来,但他又想知道最从一个数字到另一个数字最少需要多少步,现在请你帮忙。
另外,小明的密码箱很奇怪,只有四位数,上面的数字只有1到9,每次只能让每位数加1或者减1。按常识我们可以知道从1到9只需要减1,从9到1只需要加1。此外,你还能交换相邻的两个数字。如1234可以在一步后变成2134,但不能变成4231。
输入
第一行有一个整数:T,代表有多少组测试数据。
接下来T行,每行有两个整数(都是四位数),第一个是初状态,第二个是目标状态。
输出
每组数据输出一个整数,占一行。
样例输入
2
1234 2144
1111 9999
样例输出
24
一道bfs应用的题目
密码锁的操作有三种
第一种是上滑
第二种是下滑
第三种是交换
值得注意的是上滑下的时候,如果数字是9,可以直接一步滑到1
同样道理,如果数字是1,也可以一步滑到9
然后是对字符串的处理,题目中字符串长度为4,可以用数组vis来判重(四位数最大才9999)
bfs模板
要么用队列实现,要么用数组实现
void bfs()
{
q.push();
vis[]=1;
while(!q.empty())
{
q.front();
q.pop();
if()
{
}
for()
{
if()
{
q.push();
}
}
}
}
AC代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
char s1[6],s2[6];
int ans;
int vis[10000];
int in(char s[])
{
if(!vis[(s[0]-'0')*1000+(s[1]-'0')*100+(s[2]-'0')*10+(s[3]-'0')])
{
vis[(s[0]-'0')*1000+(s[1]-'0')*100+(s[2]-'0')*10+(s[3]-'0')]=1;
return 1;
}
return 0;
}
struct f
{
char s[6];
int step;
};
void bfs()
{
queue<f>ff;
f a;
f b;
strcpy(a.s,s1);
a.step=0;
if(in(a.s))
ff.push(a);
while(!ff.empty())
{
b=ff.front();
ff.pop();
if(strcmp(b.s,s2)==0)
{
ans=b.step;
return;
}
for(int i=0; i<4; i++)
{
char t=b.s[i];
b.step++;
if(b.s[i]!='9')
{
b.s[i]++;
}
else
{
b.s[i]='1';
}
if(in(b.s))
{
ff.push(b);
}
b.s[i]=t;
if(b.s[i]!='1')
{
b.s[i]--;
}
else
{
b.s[i]='9';
}
if(in(b.s))
{
ff.push(b);
}
b.s[i]=t;
if(i<3)
{
b.s[i]=b.s[i+1];
b.s[i+1]=t;
if(in(b.s))
{
ff.push(b);
}
b.s[i+1]=b.s[i];
b.s[i]=t;
}
b.step--;
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%s%s",s1,s2);
memset(vis,0,sizeof(vis));
bfs();
printf("%d\n",ans);
}
return 0;
}