zoukankan      html  css  js  c++  java
  • 搜索 问题 D: 神奇密码锁

    这里写图片描述
    这道题个人认为隐含着状态转换,所以想到的还是BFS,将其中一位数加一或减一或交换临近两位,进入下一状态,使用一个大小为10000的bool数组判重,由于BFS的特性,得到的一定是最小步数;
    普通BFS代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<set>
    using namespace std;
    const int MaxSize = 1e5;
    typedef struct node{
        int a[4];
        int step;
    }Node;
    
    Node Q[MaxSize];
    
    bool visit[10005];
    
    bool search_table(int *a){
        int tmp=0;
        tmp = a[0]*1000+a[1]*100+a[2]*10+a[3];
        if(visit[tmp])return false;
        visit[tmp] = true;
        return true;
    }
    
    int BFS(int *start,int *goal){
        int head=0,tail=1,tmp;
        memset(visit,0,sizeof(visit));
        Node t,s;
        memcpy(t.a,start,4*sizeof(int));
        t.step = 0;
        Q[head] = t;
        while(head!=tail){
            t = Q[head];
            if(!memcmp(t.a,goal,4*sizeof(int))) return t.step;
            for(int i=0;i<4;i++){
                s = t;
                s.a[i]++;
                s.step++;
                if(s.a[i]>9) s.a[i]=1;
                if(search_table(s.a)) {
                        Q[tail]=s;
                tail=(tail+1)%MaxSize;
                }
            }
            for(int i=0;i<4;i++){
                s = t;
                s.a[i]--;
                s.step++;
                if(s.a[i]<1) s.a[i]=9;
                if(search_table(s.a)) {
                        Q[tail]=s;
                tail=(tail+1)%MaxSize;
                }
            }
            for(int i=0;i<3;i++){
                s = t;
                tmp = s.a[i],s.a[i] = s.a[i+1],s.a[i+1] = tmp;
                s.step++;
                if(search_table(s.a)) {
                        Q[tail]=s;
                tail=(tail+1)%MaxSize;
                }
            }
            head=(head+1)%MaxSize;
        }
        return -1;
    }
    
    void Input_data(int *start,int *goal){
        char c[5];
        scanf("%s",c);
        for(int i=0;i<4;i++) start[i] = c[i]-'0';
        scanf("%s",c);
        for(int i=0;i<4;i++) goal[i] = c[i]-'0';
    }
    
    int main(){
        int T,start[4],goal[4];
        scanf("%d",&T);
        while(T--){
            Input_data(start,goal);
            printf("%d
    ",BFS(start,goal));
        }
    }
    

    双向BFS:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    
    int visit[10005];
    const int MaxSize = 1e5;
    typedef struct node{
        int a[4],step;
    }Node;
    Node start,goal;
    int trans(Node x){
        int tmp = 0;
        for(int i=0;i<4;i++) tmp = tmp*10+x.a[i];
        //printf("%d
    ",tmp);
        return tmp;
    }
    
    Node Q1[MaxSize],Q2[MaxSize];
    
    int BFS(){
        memset(visit,0,sizeof(visit));
        //queue<Node> Q1,Q2;
    
        Node t,s;
        int step1=0,step2=0,ans,cnt;
        int head1=0,head2=0,tail1=1,tail2=1;
        start.step = 0;
        goal.step = 0;
        Q1[head1] = start;
        Q2[head2] = goal;
        visit[trans(start)]=1;
        visit[trans(goal)]=2;
        while(true){
                cnt = (tail1-head1+MaxSize)%MaxSize;
                while(cnt--){
                    t = Q1[head1];
                    if(!memcmp(t.a,goal.a,sizeof(goal.a))) return t.step;
                    step1 = t.step + 1;
                    for(int i=0;i<4;i++){
                        s = t;
                        s.a[i]++;
                        if(s.a[i]>9) s.a[i]=1;
                        ans = trans(s);
                        if(visit[ans]==2) return step1+step2;
                        if(!visit[ans]){
                            visit[ans] = 1;
                            s.step = step1;
                            Q1[tail1]=s;
                            tail1=(tail1+1)%MaxSize;
                        }
                    }
                     for(int i=0;i<4;i++){
                        s = t;
                        s.a[i]--;
                        if(s.a[i]<1) s.a[i]=9;
                        ans = trans(s);
                        if(visit[ans]==2) return step1+step2;
                        if(!visit[ans]){
                            visit[ans] = 1;
                            s.step = step1;
                            Q1[tail1]=s;
                            tail1=(tail1+1)%MaxSize;
                        }
                    }
                    for(int i=0;i<3;i++){
                        s = t;
                        swap(s.a[i],s.a[i+1]);
                        ans = trans(s);
                        if(visit[ans]==2) return step1+step2;
                        if(!visit[ans]){
                            visit[ans] = 1;
                            s.step = step1;
                            Q1[tail1]=s;
                            tail1=(tail1+1)%MaxSize;
                        }
                    }
                    head1=(head1+1)%MaxSize;
                }
                cnt = (tail2-head2+MaxSize)%MaxSize;
                while(cnt--){
                     t = Q2[head2];
                    if(!memcmp(t.a,start.a,sizeof(start.a))) return t.step;
                    step2 = t.step + 1;
                    for(int i=0;i<4;i++){
                        s = t;
                        s.a[i]++;
                        if(s.a[i]>9) s.a[i]=1;
                        ans = trans(s);
                        if(visit[ans]==1) return step1+step2;
                        if(!visit[ans]){
                            visit[ans] = 2;
                            s.step = step2;
                            Q2[tail2]=s;
                            tail2=(tail2+1)%MaxSize;
                        }
                    }
                     for(int i=0;i<4;i++){
                        s = t;
                        s.a[i]--;
                        if(s.a[i]<1) s.a[i]=9;
                        ans = trans(s);
                        if(visit[ans]==1) return step1+step2;
                        if(!visit[ans]){
                            visit[ans] = 2;
                            s.step = step2;
                            Q2[tail2]=s;
                            tail2=(tail2+1)%MaxSize;
                        }
                    }
                    for(int i=0;i<3;i++){
                        s = t;
                        swap(s.a[i],s.a[i+1]);
                        ans = trans(s);
                        if(visit[ans]==1) return step1+step2;
                        if(!visit[ans]){
                            visit[ans] = 2;
                            s.step = step2;
                            Q2[tail2]=s;
                            tail2=(tail2+1)%MaxSize;
                        }
                    }
                    head2 = (head2+1)%MaxSize;
                }
        }
    }
    void Input_and_solve(){
        char ch[5];
        scanf("%s",ch);
        for(int i=0;i<4;i++) start.a[i] = ch[i]-'0';
        scanf("%s",ch);
        for(int i=0;i<4;i++) goal.a[i] = ch[i]-'0';
        printf("%d
    ",BFS());
    }
    int main(){
        int T;
        scanf("%d",&T);
        while(T--){
            Input_and_solve();
        }
    }
    //如有错误,还请留言指出
  • 相关阅读:
    第二周作业
    求最大值及下标编程总结
    查找整数编程总结
    课程设计第一次实验总结
    第十二周作业
    第十一周作业
    第十周作业
    第九周作业
    第八周作业
    第七周作业
  • 原文地址:https://www.cnblogs.com/Pretty9/p/7347722.html
Copyright © 2011-2022 走看看