zoukankan      html  css  js  c++  java
  • HDU——1195Open the Lock(双向BFS)

    Open the Lock

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 6016    Accepted Submission(s): 2680

    Problem Description
    Now an emergent task for you is to open a password lock. The password is consisted of four digits. Each digit is numbered from 1 to 9. 
    Each time, you can add or minus 1 to any digit. When add 1 to '9', the digit will change to be '1' and when minus 1 to '1', the digit will change to be '9'. You can also exchange the digit with its neighbor. Each action will take one step.

    Now your task is to use minimal steps to open the lock.

    Note: The leftmost digit is not the neighbor of the rightmost digit.
     
    Input
    The input file begins with an integer T, indicating the number of test cases. 

    Each test case begins with a four digit N, indicating the initial state of the password lock. Then followed a line with anotther four dight M, indicating the password which can open the lock. There is one blank line after each test case.
     
    Output
    For each test case, print the minimal steps in one line.
     
    Sample Input
    2 1234 2144 1111 9999
     
    Sample Output
    2 4
     
    Author
    YE, Kai

    最近懂了点BFS套路,这题用普通BFS本来就是大水题一道,但是可以用双向BFS写,据说若干若原来复杂度为K^n,则双向会大约是2*K^(n/2)。在POJ上的题目比较明显,从400+MS降到16MS。但是这题两者都是62MS(我搞了半天这结果一样……)代码WA很久,不解一个下午,也改了很久,看了很多其他人写的这题的题解,代码量比较大而且我使用字符数组他们是转换为int。方式不同也看起来比较复杂不太能懂。但是想起来中途看到一篇讲双向BFS的文章双向BFS,然后发现自己跟作者讲的情况很符合,似乎是搜索的时候跳出太快了,没有搜完就结束了。也就是所谓的每一层都要搜遍。然后按照作者所说加了个队列数量判断来保持两个搜索队列大小相对平衡,然后就开心地过了。

    双搜WA的可以看下这组数据(类似于答案应该是前两位交换,后两位加减):

    5
    1919
    9128

    原来代码答案是4,但其实是3(1、9交换,后面加减)。

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdlib>
    #include<sstream>
    #include<cstring>
    #include<cstdio>
    #include<string>
    #include<deque>
    #include<stack>
    #include<cmath>
    #include<queue>
    #include<set>
    #include<map>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define MM(x) memset(x,0,sizeof(x))
    #define MMINF(x) memset(x,INF,sizeof(x))
    typedef long long LL;
    const double PI=acos(-1.0);
    const int N=100010;
    struct info
    {
        char s[5];
        int step;
    };
    info goal,ori;
    int pos[N];
    int vis[N];
    inline int change(char s[])
    {
        int r=0;
        for (int i=0; i<4; ++i)
            r=r*10+s[i]-'0';
        return r;
    }
    int T_bfs()
    {
        queue<info>Qf;
        queue<info>Qb;
        Qf.push(ori);
        Qb.push(goal);
        while ((!Qf.empty())||(!Qb.empty()))
        {
            if(!Qf.empty()&&(Qf.size()>Qb.size()))//这里加了个数量判断就AC了
            {
                info now1=Qf.front();
                Qf.pop();
                for (int i=0; i<4; i++)
                {
                    info v=now1;
                    v.s[i]--;
                    if(v.s[i]<49)
                        v.s[i]='9';
                    int num=change(v.s);
                    if(!pos[num])
                    {
                        v.step=now1.step+1;
                        pos[num]=1;
                        vis[num]=v.step;
                        Qf.push(v);
                    }
                    else if(pos[num]==2)
                        return vis[num]+vis[change(now1.s)];
                }
                for (int i=0; i<4; i++)
                {
                    info v=now1;
                    v.s[i]++;
                    if(v.s[i]>57)
                        v.s[i]='1';
                    int num=change(v.s);
                    if(!pos[num])
                    {
                        v.step=now1.step+1;
                        pos[num]=1;
                        vis[num]=v.step;
                        Qf.push(v);
                    }
                    else if(pos[num]==2)
                        return vis[num]+vis[change(now1.s)];
                }
                for (int i=0; i<3; i++)
                {
                    info v=now1;
                    swap(v.s[i],v.s[i+1]);
                    int num=change(v.s);
                    if(!pos[num])
                    {
                        pos[num]=1;
                        v.step=now1.step+1;
                        vis[num]=v.step;
                        Qf.push(v);
                    }
                    else if(pos[num]==2)
                        return vis[num]+vis[change(now1.s)];
                }
            }
         
            if(!Qb.empty())
            {
                info now2=Qb.front();
                Qb.pop();
                for (int i=0; i<4; i++)
                {
                    info v=now2;
                    v.s[i]--;
                    if(v.s[i]<49)
                        v.s[i]='9';
                    int num=change(v.s);
                    if(!pos[num])
                    {
                        v.step=now2.step+1;
                        pos[num]=2;
                        vis[num]=v.step;
                        Qb.push(v);
                    }
                    else if(pos[num]==1)
                        return vis[num]+vis[change(now2.s)];
                }
                for (int i=0; i<4; i++)
                {
                    info v=now2;
                    v.s[i]++;
                    if(v.s[i]>57)
                        v.s[i]='1';
                    int num=change(v.s);
                    if(!pos[num])
                    {
                        v.step=now2.step+1;
                        pos[num]=2;
                        vis[num]=v.step;
                        Qb.push(v);
                    }
                    else if(pos[num]==1)
                        return vis[num]+vis[change(now2.s)];
                }            
                for (int i=0; i<3; i++)
                {
                    info v=now2;
                    swap(v.s[i],v.s[i+1]);
                    int num=change(v.s);
                    if(!pos[num])
                    {
                        v.step=now2.step+1;
                        pos[num]=2;
                        vis[num]=v.step;
                        Qb.push(v);
                    }
                    else if(pos[num]==1)
                        return vis[num]+vis[change(now2.s)];            
                }
            }
        }
    }
    int main(void)
    {
        int tcase;
        scanf("%d",&tcase);
        while (tcase--)
        {
            MM(pos);
            MM(vis);
            scanf("%s %s",ori.s,goal.s);
            ori.step=0;
            goal.step=0;
            pos[change(ori.s)]=1;
            pos[change(goal.s)]=2;
            vis[change(ori.s)]=0;
            vis[change(goal.s)]=0;
            !strcmp(ori.s,goal.s)?puts("0"):printf("%d
    ",T_bfs()+1);
        }
        return 0;
    }
  • 相关阅读:
    jwplayer播放器停止 单页内多个jwplayer对象停止问题
    jquery.smint.js 页面菜单浮动之谷歌浏览器异常
    jquery获取不到append出来的新元素的解决办法
    Received an invalid response. Origin 'null' is therefore not allowed access
    Java中转UTC时间字符串(含有T Z)为local时间
    OSS 图片处理流程
    java8中的map 和reduce
    MySQL的语句执行顺序
    数据库死锁解决办法
    mysql查询用if控制显示列
  • 原文地址:https://www.cnblogs.com/Blackops/p/5766310.html
Copyright © 2011-2022 走看看