• uva704


    链接:Miku

    ------------------------

    思路简单,双向bfs,实现困难

    ---------------------------

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn=100003;
    int f,ans1,ans2,head[maxn],nex[maxn],fr[maxn],mov[maxn],step[maxn];
    int ansi[maxn][25],si[maxn][25],now[25],goal[24]={0,3,4,3,0,5,6,5,0,1,2,1,0,7,8,7,0,9,10,9,0};
    int anhead[maxn],annex[maxn],anfr[maxn],anmov[maxn];
    int t;
    int check(){
        for(int i=0;i<=20;++i) 
            if(now[i]!=goal[i]) 
                return 0;
        return 1;
    }
    int cmp(int *a,int *b){
        for(int i=0;i<=20;++i)
            if(a[i]!=b[i])
                return 0;
        return 1;
    }
    int hashh(int x){
        int s=0;
        for(int i=1;i<=20;++i){
            s=(s*11+si[x][i])%maxn;
        }
        return s;
    }
    int check2(int x){
        int h=hashh(x);
        int u=anhead[h];
        while(u){
            if(cmp(ansi[u],si[x])){
                ans2=u;
                return 1;
            }
            u=annex[u];
        }
        return 0;
    }
    int add(int x){//x状态的所有拓展状态 
        int h=hashh(x);
        int u=head[h];
        while(u){
            if(cmp(si[u],si[x])){
                return 0;
            }
            u=nex[u];
        }
        nex[x]=head[h];//链表 
        head[h]=x;
        return 1;
    }
    void bfs(int *x,int now){
        int tail=0,front=1;
        step[0]=0;
        for(int i=0;i<=20;++i) si[0][i]=x[i];
        memset(head,0,sizeof(head));
        memset(nex,0,sizeof(nex));
        add(0);
        while(tail<front){
            if(now&&check2(tail)){
                f=1;
                ans1=tail;
                break;
            }
            if(step[tail]>8)
            break;
            for(int i=0;i<=9;++i)
            si[front][i+2]=si[tail][i];
            si[front][0]=si[tail][10];
            si[front][1]=si[tail][11];
            for(int i=12;i<=20;++i) 
            si[front][i]=si[tail][i];
            if(add(front)){
                step[front]=step[tail]+1;
                mov[front]=1;
                fr[front]=tail;
                front++;
            }
            for(int i=9;i<=18;++i)
            si[front][i]=si[tail][i+2];
            si[front][19]=si[tail][9];
            si[front][20]=si[tail][10];
            for(int i=0;i<=8;++i) 
            si[front][i]=si[tail][i];
            if(add(front)){
                step[front]=step[tail]+1;
                mov[front]=2;
                fr[front]=tail;
                front++;
            }
            for(int i=0;i<=9;++i)
            si[front][i]=si[tail][i+2];
            si[front][10]=si[tail][0];
            si[front][11]=si[tail][1];
            for(int i=12;i<=20;++i) 
            si[front][i]=si[tail][i];
            if(add(front)){
                step[front]=step[tail]+1;
                mov[front]=3;
                fr[front]=tail;
                front++;
            }
            for(int i=9;i<=18;++i)
            si[front][i+2]=si[tail][i];
            si[front][9]=si[tail][19];
            si[front][10]=si[tail][20];
            for(int i=0;i<=8;++i) 
            si[front][i]=si[tail][i];
            if(add(front)){
                step[front]=step[tail]+1;
                mov[front]=4;
                fr[front]=tail;
                front++;
            }
            tail++;
        }
    }
    void printmov(int x){
        if(x){
            printmov(fr[x]);
            printf("%d",mov[x]);
        }
    }
    void anprint(int x){
        if(x){
            if(anmov[x]==2)
            printf("4");
            else
            printf("%d",(anmov[x]+2)%4);
            anprint(anfr[x]);
        }
    }
    int main(){
        scanf("%d",&t);
        bfs(goal,0);
        memcpy(anhead,head,sizeof(head));//an==从答案 
        memcpy(annex,nex,sizeof(nex));
        memcpy(anfr,fr,sizeof(fr));
        memcpy(anmov,mov,sizeof(mov));
        memcpy(ansi,si,sizeof(si));
        for(int i=1;i<=t;++i){
            for(int j=0;j<=23;++j)
            scanf("%d",&now[j]);
                if(check()){
                    cout<<"PUZZLE ALREADY SOLVED
    ";
                    continue;
                }
                ans1=ans2=0;//答案坐标 
                f=0;
                bfs(now,1);
                if(f){
                    printmov(ans1);
                    anprint(ans2);
                    cout<<endl;
                }else{
                    cout<<"NO SOLUTION WAS FOUND IN 16 STEPS
    ";
                }
        }
    }
  • 相关阅读:
    页面加载完毕相关信息淡入效果
    导航菜单底部滑动条跟随效果
    我要成为优秀的前端一员!
    (转)git合并多个commit
    Windows 7 + PHP 5.3 + WAMP 下 Imagick 扩展安装
    使用 PHP 框架 Yii 访问 MS SQL 的尝试
    拼合逐月数据系列
    编程视频教程推荐
    Java 实现 Domino邮箱自动注册
    二、 编写一个类,用两个栈实现队列,支持队列的基本操作(add,poll,peek)
  • 原文地址:https://www.cnblogs.com/For-Miku/p/13411598.html
Copyright © 2020-2023  润新知