hnust - 神奇密码锁 - BFS

题目描述

 小明忘记了旅行箱上的密码,现在他想自己暴力弄出密码来,但他又想知道最从一个数字到另一个数字最少需要多少步,现在请你帮忙。
另外,小明的密码箱很奇怪,只有四位数,上面的数字只有1到9,每次只能让每位数加1或者减1。按常识我们可以知道从1到9只需要减1,从9到1只需要加1。此外,你还能交换相邻的两个数字。如1234可以在一步后变成2134,但不能变成4231。

输入

第一行有一个整数:T,代表有多少组测试数据。
接下来T行,每行有两个整数(都是四位数),第一个是初状态,第二个是目标状态。

输出

每组数据输出一个整数,占一行。

样例输入

2
1234 2144
1111 9999

样例输出

2
4

题解

  • 据题意暴力破解有三种方案,上滑,下滑,交换,这三个操作是平行操作。
  • 因为题意是求最短步骤,显然用广度优先搜索(BFS)。
  • 当然BFS直接写提交TLE,这里又要考虑判重,具体判重就是用有一个hash数组vis[],因为最大9999,数组大小在10^5以内,开销不大,查找也快。
#include 
#include 
#include 
#include 
#include 
using namespace std;
const int MAXN=0x3f3f3f3f;
struct Node
{
    char s[6];
    int stp;
};
char st[6],go[6];
bool vis[10000];
bool In(char s[])
{
    int t=(s[0]-'0')*1000+(s[1]-'0')*100+(s[2]-'0')*10+(s[3]-'0');
    if(!vis[t]){
        vis[t]=1;//标记为已访问
        return true;
    }
    return false;
}
int ans=0;
void bfs()
{
    queue que;
    Node s;
    strcpy(s.s,st);
    s.stp=0;
    if(In(s.s))
        que.push(s);
    while(!que.empty()){
        s=que.front();que.pop();
        //strcmp(s.s,go)==0
        //strcmp和memcmp用法都是为了判断字符串是否同等
        if(memcmp(s.s,go,sizeof(char)*4)==0){
            ans=s.stp;return;
        }
        for(int i=0;i<4;i++)
        {
            char t=s.s[i];
            s.stp++;
            //密码上滑,s[i]++的操作
            if(s.s[i]!='9') s.s[i]++;
            else s.s[i]='1';//特殊情况
            if(In(s.s)){
                que.push(s);
            }
            s.s[i]=t;//还原s[i]
            //密码下滑,s[i]--的操作
            if(s.s[i]!='1') s.s[i]--;
            else s.s[i]='9';
            if(In(s.s)){
                que.push(s);
            }
            s.s[i]=t;
            if(i<3){//交换相邻的两个数字
                char tem=s.s[i+1];
                s.s[i+1]=s.s[i];
                s.s[i]=tem;
                if(In(s.s)){
                    que.push(s);
                }
                s.s[i]=t;
                s.s[i+1]=tem;
            }
            s.stp--;//还原
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%s%s",st,go);
        memset(vis,0,sizeof(vis));
        bfs();
        printf("%d\n",ans);
    }
}

你可能感兴趣的:(C/C++,搜索)