【bfs】密码锁-C++

Description
现在一个紧急的任务是打开一个密码锁。密码由四位数字组成,每个数字从 1 到 9 进行编号。每次可以对任何数字加 1 或减 1。当将9加 1 时,数字将变为1,当1减 1 的时,数字将变为9。您也可以与邻居交换数字,每一个行动记做一步。现在你的任务是使用最小的步骤来打开锁。
注意:最左边的数字不是最右边数字的邻居。
Input	
第一行输入四位数字,表示密码锁的初始状态。第二行输入四位数字,表示开锁的密码。
Output
输出一个整数,表示最小步骤。
Sample Input 1 
1234
2144
Sample Output 1
2

这道题一看,似乎不该用搜索。
又一想,这种题目也只能使用bfs来完成。

但是怎么打标记?

普通的一维的vis数组已经无法满足这道题目的需求了,应该怎么解决?
再认真一看,它的起始和重点都是4个数字构成,我们可以把由4个数字组成的一组密码记为一种状态,即:
当密码为abcd时,对应的标记就应该记为vis[a][b][c][d]=1;
简单来说,就是通过四维数组,完成打标记这一步。
接下来的操作就是最基本的bfs,代码随便敲下来就可以了。
按照题意,每个密码能够进行的拓展操作分别为:
每一位加/减一位构成的新密码;
分别交换第1,2/2,3/3,4位构成的新密码;
然后判断,如果是没有打标记的,打进队列然后打标记即可。

AC代码:

#include<bits/stdc++.h>
using namespace std;

struct node
{
    int aa[4];
    int t;
    node(){};
    node(int a0,int a1,int a2,int a3,int t_)
    {
        aa[0]=a0;
        aa[1]=a1;
        aa[2]=a2;
        aa[3]=a3;
        t=t_;
    }
}mb;//mb:目标 
bool x[10][10][10][10];
queue<node> qu;


bool in(node a)
{
    if(a.aa[0]==mb.aa[0]&&a.aa[1]==mb.aa[1]&&a.aa[2]==mb.aa[2]&&a.aa[3]==mb.aa[3])return false;
    else return true;
}

int bfs(int a,int b,int c,int d)
{
    qu.push(node(a,b,c,d,0));
    x[a][b][c][d]=1;
    while(in(qu.front())&&!qu.empty())
    {
        node now=qu.front();
        qu.pop();
        
        
        if(!x[now.aa[1]][now.aa[0]][now.aa[2]][now.aa[3]])
        {
            qu.push(node(now.aa[1],now.aa[0],now.aa[2],now.aa[3],now.t+1));
            x[now.aa[1]][now.aa[0]][now.aa[2]][now.aa[3]]=1;
        }
        //a,b,c,d->b,a,c,d 
        
        if(!x[now.aa[0]][now.aa[2]][now.aa[1]][now.aa[3]])
        {
            qu.push(node(now.aa[0],now.aa[2],now.aa[1],now.aa[3],now.t+1));
            x[now.aa[0]][now.aa[2]][now.aa[1]][now.aa[3]]=1;
        }
        //a,b,c,d->a,c,b,d
        
        if(!x[now.aa[0]][now.aa[1]][now.aa[3]][now.aa[2]])
        {
            qu.push(node(now.aa[0],now.aa[1],now.aa[3],now.aa[2],now.t+1));
            x[now.aa[0]][now.aa[1]][now.aa[3]][now.aa[2]]=1;
        }
        //a,b,c,d->a,b,d,c
        //因为a和d 不能直接交换所以就只有这三种情况 
        for(int i=0;i<4;i++)
        {
            node nxt=now;
            
            nxt.aa[i]++;
            nxt.t++;
            
            if(nxt.aa[i]==10)nxt.aa[i]=1;
            
            if(!x[nxt.aa[0]][nxt.aa[1]][nxt.aa[2]][nxt.aa[3]])
            {
                qu.push(nxt);
                x[nxt.aa[0]][nxt.aa[1]][nxt.aa[2]][nxt.aa[3]]=1;
            }
            
        }
        
        for(int i=0;i<4;i++)
        {
            node nxt=now;
            
            nxt.aa[i]--;
            nxt.t++;
            
            if(nxt.aa[i]==0)nxt.aa[i]=9;
            
            if(!x[nxt.aa[0]][nxt.aa[1]][nxt.aa[2]][nxt.aa[3]])
            {
                qu.push(nxt);
                x[nxt.aa[0]][nxt.aa[1]][nxt.aa[2]][nxt.aa[3]]=1;
            }
            
        }
    }
    
    return qu.front().t;
    
}

int main()
{
    int st,ed;
    cin>>st>>ed;
    
    mb=node(ed/1000,ed%1000/100,ed%100/10,ed%10,0);
    
    cout<<bfs(st/1000,st%1000/100,st%100/10,st%10)<<endl;
    return 0;
}

ov.

posted @ 2019-06-02 15:55  摸鱼酱  阅读(1256)  评论(0编辑  收藏  举报