hdu1195Open the Lock(双向bfs+循环队列)

->题目请戳这里<-

题目大意:给2个长度为4的数字串,求从第一个串变到第二个串最少要几步。

每一步变换情况有:

1:每个数字+1,9+1 = 1;

2:每个数字-1,1-1 = 9;

3:某个数字和与其相邻的数字交换,第一个和最后一个数字不算相邻。

题目分析:bfs~,这题单向bfs也可以过,不过想练习一下双向bfs,话说还是第一次写双向bfs。所以先找道简单的切。队列决定自己写,省时间,用循环队列节省空间。不过跑出来好像也不是很快,进不了0ms,好吧,我又写挫了。。。

单向bfs:

#include<iostream>
#include<queue>
#include<cstring>
using namespace std;

char s1[5],s2[5];
bool mark[10][10][10][10];

struct node{
    char s[5];
    int count;
}t,now,last;

void Bfs()
{
    queue<node>q;
    memset(mark,0,sizeof(mark));
    strcpy(t.s,s1);
    t.count = 0;
    mark[t.s[0] - '0'][t.s[1] - '0'][t.s[2] - '0'][t.s[3] - '0'] = 1;
    q.push(t);
    while(!q.empty())
    {
        now = q.front();
        q.pop();
        if(strcmp(s2,now.s) == 0)
        {
            printf("%d\n",now.count);
            return;
        }
        char c;
        for(int i = 0;i < 4;i ++)
        {
            if(i < 3)//该数字与右边的换
            {
                strcpy(t.s,now.s);
                c = t.s[i];
                t.s[i] = t.s[i+1];
                t.s[i+1] = c;
                if(!mark[t.s[0] - '0'][t.s[1] - '0'][t.s[2] - '0'][t.s[3] - '0'])
                {
                    t.count = now.count + 1;
                    mark[t.s[0] - '0'][t.s[1] - '0'][t.s[2] - '0'][t.s[3] - '0'] = 1;
                    if(strcmp(s2,t.s) == 0)
                    {
                        printf("%d\n",t.count);
                        return;
                    }
                    q.push(t);
                }
            }
            strcpy(t.s,now.s);
            t.s[i] = now.s[i] + 1;//加法
            if(t.s[i] - '0' > 9)
                t.s[i] = '1';
            if(!mark[t.s[0] - '0'][t.s[1] - '0'][t.s[2] - '0'][t.s[3] - '0'])
            {
                t.count = now.count + 1;
                mark[t.s[0] - '0'][t.s[1] - '0'][t.s[2] - '0'][t.s[3] - '0'] = 1;
                if(strcmp(s2,t.s) == 0)
                {
                    printf("%d\n",t.count);
                    return;
                }
                q.push(t);
            }
            strcpy(t.s,now.s);
            t.s[i] = now.s[i] - 1;//减法
            if(t.s[i] - '0' == 0)
                t.s[i] = '9';
            if(!mark[t.s[0] - '0'][t.s[1] - '0'][t.s[2] - '0'][t.s[3] - '0'])
            {
                t.count = now.count + 1;
                mark[t.s[0] - '0'][t.s[1] - '0'][t.s[2] - '0'][t.s[3] - '0'] = 1;
                if(strcmp(s2,t.s) == 0)
                {
                    printf("%d\n",t.count);
                    return;
                }
                q.push(t);
            }
        }
    }
}
int main(){
    int t;
    scanf("%d",&t);
    while(t --)
    {
        scanf("%s%s",s1,s2);
        Bfs();
    }
    return 0;
}//31MS	344K
双向bfs:

#include <iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
using namespace std;
int flag[2][10][10][10][10];
char s1[10],s2[10];
char ss[10],now[10];
struct que
{
    char s[100005][10];
    int head,tail,size;
    void init()
    {
        head = tail = 0;
        size = 100005;
    }
    bool empty()
    {
        return head == tail;
    }
    char * top()
    {
        return s[head];
    }
    void pop()
    {
        head ++;
        head %= size;
    }
    void push(char a[])
    {
        strcpy(s[tail],a);
        tail ++;
        tail %= size;
    }
}q[2];

int Bfs()
{
    int i,j;
    q[0].init();
    q[1].init();
    int step = 0;
    memset(flag,-1,sizeof(flag));
    if(strcmp(s1,s2) == 0)
        return 0;
    q[0].push(s1);//正向搜
    q[1].push(s2);//反向搜
    flag[0][s1[0] - '0'][s1[1] - '0'][s1[2] - '0'][s1[3] - '0'] = 0;
    flag[1][s2[0] - '0'][s2[1] - '0'][s2[2] - '0'][s2[3] - '0'] = 0;
    while(!q[0].empty() && !q[1].empty())
    {
        for(i = 0;i <= 1;i ++)
        {
            strcpy(now,q[i].top());
            q[i].pop();
            step = flag[i][now[0] - '0'][now[1] - '0'][now[2] - '0'][now[3] - '0'];
            for(j = 0;j < 4;j ++)
            {
                if(j < 3)//与右边交换
                {
                    strcpy(ss,now);
                    char c = ss[j];
                    ss[j] = ss[j + 1];
                    ss[j + 1] = c;
                    if(flag[i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'] == -1)
                    {
                        flag[i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'] = 1 + step;
                        if(flag[1 - i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'] != -1)
                        {
                            return 1 + step + flag[1 - i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'];
                        }
                        q[i].push(ss);
                    }
                }
                strcpy(ss,now);
                if(ss[j] == '9')
                    ss[j] = '1';
                else
                    ss[j] ++;
                if(flag[i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'] == -1)
                {
                    flag[i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'] = 1 + step;
                    if(flag[1 - i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'] != -1)
                    {
                        return 1 + step + flag[1 - i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'];
                    }
                    q[i].push(ss);
                }
                strcpy(ss,now);
                if(ss[j] == '1')
                    ss[j] == '9';
                else
                    ss[j] --;
                if(flag[i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'] == -1)
                {
                    flag[i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'] = 1 + step;
                    if(flag[1 - i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'] != -1)
                    {
                        return 1 + step + flag[1 - i][ss[0] - '0'][ss[1] - '0'][ss[2] - '0'][ss[3] - '0'];
                    }
                    q[i].push(ss);
                }
            }
            if(!q[i].empty())//要把同一层的搜完。。。
            {
                strcpy(now,q[i].top());
                if(flag[i][now[0] - '0'][now[1] - '0'][now[2] - '0'][now[3] - '0'] == step)
                    i --;
            }
        }
    }
}

void input()
{
    char c;
    while(isspace(c = getchar()))
        ;
    s1[0] = c;
    s1[1] = getchar();
    s1[2] = getchar();
    s1[3] = getchar();
    while(isspace(c = getchar()))
        ;
    s2[0] = c;
    s2[1] = getchar();
    s2[2] = getchar();
    s2[3] = getchar();
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t --)
    {
        //scanf("%s%s",s1,s2);
        input();//还是很慢。。。
        printf("%d\n",Bfs());
    }
    return 0;
}
//15MS	440K



你可能感兴趣的:(bfs)