• 搜索 问题 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();
        }
    }
    //如有错误,还请留言指出
  • 相关阅读:
    背水一战 Windows 10 (61)
    背水一战 Windows 10 (60)
    背水一战 Windows 10 (59)
    背水一战 Windows 10 (58)
    背水一战 Windows 10 (57)
    背水一战 Windows 10 (56)
    背水一战 Windows 10 (55)
    背水一战 Windows 10 (54)
    背水一战 Windows 10 (53)
    背水一战 Windows 10 (52)
  • 原文地址:https://www.cnblogs.com/Pretty9/p/7347722.html
Copyright © 2020-2023  润新知