搜索 问题 D: 神奇密码锁

来源:互联网 发布:kanahei知乎 编辑:程序博客网 时间:2024/05/19 10:37

这里写图片描述
这道题个人认为隐含着状态转换,所以想到的还是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\n",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\n",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\n",BFS());}int main(){    int T;    scanf("%d",&T);    while(T--){        Input_and_solve();    }}//如有错误,还请留言指出
原创粉丝点击