问题 D: 神奇密码锁

来源:互联网 发布:域名被墙做跳转有用吗 编辑:程序博客网 时间:2024/05/20 13:13

今天小编又来跟新了 没办法A题目速度不高啊 本人还在处于训练状态请多多包涵

最近在训练DFS以及BFS  今天我来说说神奇密码锁问题 在做这个题目的过程中有思路 然后想上网找找 发现没有博客写关于这个问题 

所以我想讲讲我的解题思路

题目描述

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

另外,小明的密码箱很奇怪,只有四位数,上面的数字只有1到9,每次只能让每位数加1或者减1。按常识我们可以知道从1到9只需要减1,从9到1只需要加1。此外,你还能交换相邻的两个数字。如1234可以在一步后变成2134,但不能变成4231。

输入

第一行有一个整数:T,代表有多少组测试数据。

接下来T行,每行有两个整数(都是四位数),第一个是初状态,第二个是目标状态。

输出

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

样例输入

21234 21441111 9999

样例输出

24
首先在看这道题目时候我先没有考虑bfs以及dfs  我用一个3*3的二维数组来处理该位数字转换为其他位置上数字所需要的步数(包括互换),然后处理四次就可以了,我这样想过但是没有进行实现 感觉应该可以

好下面说一下DFS以及BFS的方法,我首先解释一下一个数变化有11种情况(每一位数字加减共8种  互换数字有三种  共11种)。我在分析的过程中把DFS排除了 因为在你往下走的过程中深度很大,你不知道跳出循环条件是什么 不过我今天听别人讲可以限制它的深度 如果在限制的深度中还是没有找到你要的答案 可以进一步加大深度直到你找到你的目标为止

至于BFS,其实思路是比较简单的 使用容器STL的队列 然后使用一个大小为10005的判断数组 如果走过为1 没有则为0 然后就是BFS的老套路了 先处理对头元素  取对头元素 (判断) 然后就是扩展 看是否走过 如果走过则跳过 如果没有则push 一直到找到目标为止

#include <iostream>#include <algorithm>#include <queue>#include <stdio.h>#include <cstring>using namespace std;int pangduan[11000]={0};int bf(int y,int z){    if (y+z==10) return 1;    if (y+z==0) return 9;    else return y+z;}typedef struct password{    int a,b,c,d,m;}password;int L[32]={1,0,0,0,-1,0,0,0,0,1,0,0,0,-1,0,0,0,0,1,0,0,0,-1,0,0,0,0,1,0,0,0,-1};queue<password>Q;int bfs(password,password);int main(){    password W1,W2;    int n,m;    scanf("%d",&n);    while(n--)    {        memset(pangduan,0,sizeof(pangduan));        scanf("%d",&m);        W1.d=m%10;m=m/10;W1.c=m%10;m=m/10;W1.b=m%10;W1.a=m/10;        scanf("%d",&m);        W2.d=m%10;m=m/10;W2.c=m%10;m=m/10;W2.b=m%10;W2.a=m/10;        W1.m=W2.m=0;        m=bfs(W1,W2);        printf("%d\n",m);    }    return 0;}int bfs(password a,password b){    Q.push(a);    password c;    int shu;    while(!Q.empty())    {        c=Q.front();Q.pop();        if(c.a==b.a&&c.b==b.b&&c.c==b.c&&c.d==b.d)        {            while(!Q.empty()) {Q.pop();}            return c.m;        }        for(int i=0;i<8;i++)        {            a.a=bf(c.a,L[4*i]);a.b=bf(c.b,L[4*i+1]);            a.c=bf(c.c,L[4*i+2]);a.d=bf(c.d,L[4*i+3]);            a.m=c.m+1;            shu=a.a*1000+a.b*100+a.c*10+a.d;            if(pangduan[shu]) continue;            else pangduan[shu]=1;            Q.push(a);        }        a.m=c.m+1;        a.a=c.b;a.b=c.a;a.c=c.c;a.d=c.d;shu=a.a*1000+a.b*100+a.c*10+a.d;if(!pangduan[shu]){pangduan[shu]=1;Q.push(a);}        a.a=c.a;a.b=c.c;a.c=c.b;a.d=c.d;shu=a.a*1000+a.b*100+a.c*10+a.d;if(!pangduan[shu]){pangduan[shu]=1;Q.push(a);}        a.a=c.a;a.b=c.b;a.c=c.d;a.d=c.c;shu=a.a*1000+a.b*100+a.c*10+a.d;if(!pangduan[shu]){pangduan[shu]=1;Q.push(a);}    }}
写得挺简洁的 但是当我交的时候就错了 因为发现时间超时了 做题时候没有考虑这个问题 然后我只能使用双向BFS 由于第一次敲代
简洁度有待加强
#include <iostream>#include <algorithm>#include <queue>#include <stdio.h>#include <cstring>using namespace std;int pangduan[11000]= {0};int flag[11000]= {0};int pangduan1[11000]= {0};int flag1[11000]= {0};int bf(int y,int z){    if (y+z==10) return 1;    if (y+z==0) return 9;    else return y+z;}typedef struct password{    int a,b,c,d,m;} password;int L[32]= {1,0,0,0,-1,0,0,0,0,1,0,0,0,-1,0,0,0,0,1,0,0,0,-1,0,0,0,0,1,0,0,0,-1};queue<password>Q;queue<password>P;int bfs(password,password);int main(){    password W1,W2;    int n,m;    scanf("%d",&n);    while(n--)    {        memset(pangduan,0,sizeof(pangduan));        memset(pangduan1,0,sizeof(pangduan1));        memset(flag1,0,sizeof(flag1));        memset(flag,0,sizeof(flag));        scanf("%d",&m);pangduan[m]=0;        flag[m]=1;        W1.d=m%10;        m=m/10;        W1.c=m%10;        m=m/10;        W1.b=m%10;        W1.a=m/10;        scanf("%d",&m);pangduan1[m]=0;        flag1[m]=1;        W2.d=m%10;        m=m/10;        W2.c=m%10;        m=m/10;        W2.b=m%10;        W2.a=m/10;        W1.m=W2.m=0;        while(!Q.empty()) Q.pop();        while(!P.empty()) P.pop();        m=bfs(W1,W2);        printf("%d\n",m);    }    return 0;}int bfs(password a,password b){    Q.push(a);    P.push(b);    password c;    int shu,bushu=999999;    int k=0;    while(1)    {        while(1)        {            c=Q.front();            if(c.m!=k) break;            Q.pop();            shu=c.a*1000+c.b*100+c.c*10+c.d;            if(flag1[shu]!=0)            {                if(c.m<bushu)                    bushu=c.m+pangduan1[shu];            }            for(int i=0; i<8; i++)            {                a.a=bf(c.a,L[4*i]);                a.b=bf(c.b,L[4*i+1]);                a.c=bf(c.c,L[4*i+2]);                a.d=bf(c.d,L[4*i+3]);                a.m=c.m+1;                shu=a.a*1000+a.b*100+a.c*10+a.d;                if(flag[shu]) continue;                else {pangduan[shu]=a.m;flag[shu]=1;}                Q.push(a);            }            a.m=c.m+1;            a.a=c.b;            a.b=c.a;            a.c=c.c;            a.d=c.d;            shu=a.a*1000+a.b*100+a.c*10+a.d;            if(!pangduan[shu])            {                pangduan[shu]=a.m;                flag[shu]=1;                Q.push(a);            }            a.a=c.a;            a.b=c.c;            a.c=c.b;            a.d=c.d;            shu=a.a*1000+a.b*100+a.c*10+a.d;            if(!pangduan[shu])            {                pangduan[shu]=a.m;                flag[shu]=1;                Q.push(a);            }            a.a=c.a;            a.b=c.b;            a.c=c.d;            a.d=c.c;            shu=a.a*1000+a.b*100+a.c*10+a.d;            if(!pangduan[shu])            {                pangduan[shu]=a.m;                flag[shu]=1;                Q.push(a);            }        }        if(bushu!=999999) return bushu;        while(1)        {            c=P.front();            if(c.m!=k) break;            P.pop();            shu=c.a*1000+c.b*100+c.c*10+c.d;            if(flag[shu]!=0)            {                if(c.m<bushu)                    bushu=c.m+pangduan[shu];            }            for(int i=0; i<8; i++)            {                a.a=bf(c.a,L[4*i]);                a.b=bf(c.b,L[4*i+1]);                a.c=bf(c.c,L[4*i+2]);                a.d=bf(c.d,L[4*i+3]);                a.m=c.m+1;                shu=a.a*1000+a.b*100+a.c*10+a.d;                if(flag1[shu]) continue;                else {pangduan1[shu]=a.m;flag1[shu]=1;}                P.push(a);            }            a.m=c.m+1;            a.a=c.b;            a.b=c.a;            a.c=c.c;            a.d=c.d;            shu=a.a*1000+a.b*100+a.c*10+a.d;            if(!pangduan1[shu])            {                pangduan1[shu]=a.m;                flag1[shu]=1;                P.push(a);            }            a.a=c.a;            a.b=c.c;            a.c=c.b;            a.d=c.d;            shu=a.a*1000+a.b*100+a.c*10+a.d;            if(!pangduan1[shu])            {                pangduan1[shu]=a.m;                flag1[shu]=1;                P.push(a);            }            a.a=c.a;            a.b=c.b;            a.c=c.d;            a.d=c.c;            shu=a.a*1000+a.b*100+a.c*10+a.d;            if(!pangduan1[shu])            {                pangduan1[shu]=a.m;                flag1[shu]=1;                P.push(a);            }        }        if(bushu!=999999) return bushu;        k++;    }}