神奇密码锁

题目描述


 小明忘记了旅行箱上的密码,现在他想自己暴力弄出密码来,但他又想知道最从一个数字到另一个数字最少需要多少步,现在请你帮忙。

另外,小明的密码箱很奇怪,只有四位数,上面的数字只有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;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值