HDU 1195 Open the Lock (双向BFS与单向BFS)

刚学了个双向BFS,顺便用这题来练习练习,看看效果如何。

先来个单向bfs。



用时62ms。

下面是单向BFS代码。这次写的很顺利,基本一次性写完没有调试提交就AC了。。

#include <stdio.h>
#include <string.h>
#include <queue>
#include <math.h>
using namespace std;
int vis[100000], a[5], b[5];
char s1[5], s2[5];
int jj[]= {1,-1};
struct node
{
    int a[5], ans;
};
int pan(int a[])
{
    int x=0, i;
    for(i=0; i<4; i++)
        x=x*10+a[i];
    return x;
}
void bfs()
{
    node f1, f2;
    queue<node>q;
    int i, j, k;
    for(i=0; i<4; i++)
        f1.a[i]=a[i];
    f1.ans=0;
    q.push(f1);
    vis[pan(f1.a)]=1;
    while(!q.empty())
    {
        f1=q.front();
        q.pop();
        if(pan(f1.a)==pan(b))
        {
            printf("%d\n",f1.ans);
            return ;
        }
        for(i=0; i<4; i++)
            f2.a[i]=f1.a[i];
        for(i=0; i<4; i++)
        {
            for(j=0; j<2; j++)
            {
                for(k=0; k<4; k++)
                    f2.a[k]=f1.a[k];
                f2.a[i]=f1.a[i]+jj[j];
                if(f2.a[i]==10)
                    f2.a[i]=1;
                if(f2.a[i]==0)
                    f2.a[i]=9;
                if(!vis[pan(f2.a)])
                {
                    vis[pan(f2.a)]=1;
                    f2.ans=f1.ans+1;
                    q.push(f2);
                }
            }
        }
        for(i=0; i<3; i++)
        {
            for(k=0; k<4; k++)
                f2.a[k]=f1.a[k];
            int t=f2.a[i];
            f2.a[i]=f2.a[i+1];
            f2.a[i+1]=t;
            if(!vis[pan(f2.a)])
            {
                vis[pan(f2.a)]=1;
                f2.ans=f1.ans+1;
                q.push(f2);
            }
        }
    }
}
int main()
{
    int t, i;
    scanf("%d ",&t);
    while(t--)
    {
        memset(vis,0,sizeof(vis));
        scanf("%s",s1);
        for(i=0; i<4; i++)
            a[i]=s1[i]-'0';
        scanf("%s",s2);
        for(i=0; i<4; i++)
            b[i]=s2[i]-'0';
        bfs();
    }
    return 0;
}

这是双向BFS  

用时15ms


时间上没有想象中的那么快。。但是还不错。。可能是数据比较小吧,按理说数据越大优势越明显。

双向BFS也就只是用了两个BFS同时搜索而已,一个从起点往终点找,一个从终点往起点找,然后当出现交集时便是找到了。代码如下:

#include <stdio.h>
#include <string.h>
#include <queue>
#include <math.h>
using namespace std;
int a[5], b[5];
char s1[5], s2[5];
int jj[]= {1,-1};
struct node
{
    int a[5], ans;
};
struct N
{
    int x;
    int flag;
} vis[100003];
int pan(int a[])
{
    int x=0, i;
    for(i=0; i<4; i++)
        x=x*10+a[i];
    return x;
}
void bfs()
{
    node f1, f2;
    queue<node>q1;
    queue<node>q2;
    int i, j, k;
    for(i=0; i<4; i++)
        f1.a[i]=a[i];
    f1.ans=0;
    q1.push(f1);
    vis[pan(f1.a)].flag=1;
    vis[pan(f1.a)].x=0;
    for(i=0; i<4; i++)
        f1.a[i]=b[i];
    f1.ans=0;
    q2.push(f1);
    vis[pan(f1.a)].flag=2;
    vis[pan(f1.a)].x=0;
    int st=0;
    while(!q1.empty()&&!q2.empty())
    {
        while(q1.front().ans==st)
        {
            f1=q1.front();
            //printf("%d\n",f1.ans);
            q1.pop();
            for(i=0; i<4; i++)
            {
                for(j=0; j<2; j++)
                {
                    for(k=0; k<4; k++)
                        f2.a[k]=f1.a[k];
                    f2.a[i]=f1.a[i]+jj[j];
                    if(f2.a[i]==10)
                        f2.a[i]=1;
                    if(f2.a[i]==0)
                        f2.a[i]=9;
                    f2.ans=f1.ans+1;
                    if(!vis[pan(f2.a)].flag)
                    {
                        vis[pan(f2.a)].flag=1;
                        vis[pan(f2.a)].x=f2.ans;
                        q1.push(f2);
                    }
                    else if(vis[pan(f2.a)].flag==2)
                    {
                        printf("%d\n",f2.ans+vis[pan(f2.a)].x);
                        return ;
                    }
                }
            }
            for(i=0; i<3; i++)
            {
                for(k=0; k<4; k++)
                    f2.a[k]=f1.a[k];
                int t=f2.a[i];
                f2.a[i]=f2.a[i+1];
                f2.a[i+1]=t;
                f2.ans=f1.ans+1;
                if(!vis[pan(f2.a)].flag)
                {
                    vis[pan(f2.a)].flag=1;
                    vis[pan(f2.a)].x=f2.ans;
                    q1.push(f2);
                }
                else if(vis[pan(f2.a)].flag==2)
                {
                    printf("%d\n",f2.ans+vis[pan(f2.a)].x);
                    return ;
                }
            }
        }
        while(q2.front().ans==st)
        {
            f1=q2.front();
            q2.pop();
            //printf("%d\n",f1.ans);
            for(i=0; i<4; i++)
            {
                for(j=0; j<2; j++)
                {
                    for(k=0; k<4; k++)
                        f2.a[k]=f1.a[k];
                    f2.a[i]=f1.a[i]+jj[j];
                    if(f2.a[i]==10)
                        f2.a[i]=1;
                    if(f2.a[i]==0)
                        f2.a[i]=9;
                    f2.ans=f1.ans+1;
                    if(!vis[pan(f2.a)].flag)
                    {
                        vis[pan(f2.a)].flag=2;
                        vis[pan(f2.a)].x=f2.ans;
                        q2.push(f2);
                    }
                    else if(vis[pan(f2.a)].flag==1)
                    {
                        printf("%d\n",f2.ans+vis[pan(f2.a)].x);
                        return ;
                    }
                }
            }
            for(i=0; i<3; i++)
            {
                for(k=0; k<4; k++)
                    f2.a[k]=f1.a[k];
                int t=f2.a[i];
                f2.a[i]=f2.a[i+1];
                f2.a[i+1]=t;
                f2.ans=f1.ans+1;
                if(!vis[pan(f2.a)].flag)
                {
                    vis[pan(f2.a)].flag=2;
                    vis[pan(f2.a)].x=f2.ans;
                    q2.push(f2);
                }
                else if(vis[pan(f2.a)].flag==1)
                {
                    printf("%d\n",f2.ans+vis[pan(f2.a)].x);
                    return ;
                }
            }
        }
        st++;
    }
}
int main()
{
    int t, i;
    scanf("%d ",&t);
    while(t--)
    {
        for(i=0;i<100002;i++)
            vis[i].flag=0;
        scanf("%s",s1);
        for(i=0; i<4; i++)
            a[i]=s1[i]-'0';
        scanf("%s",s2);
        for(i=0; i<4; i++)
            b[i]=s2[i]-'0';
        bfs();
    }
    return 0;
}



你可能感兴趣的:(编程,算法,C语言,bfs)