zoukankan      html  css  js  c++  java
  • code1225 八数码Bfs

    Bfs搜索

    1.把棋盘直接作为状态:

    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<cstdlib>
    using namespace std;
    
    const int n=9;
    const int Size=4;
    int flag;
    struct Point{
        int x,y;
    };
    struct Node{
        int board[Size][Size];
        Point space;
        int step;
    };
    int end[]={0, 1,2,3,8,9,4,7,6,5};
    int dx[4]={-1,0,1,0}; int dy[4]={0,1,0,-1};
    bool visited[400005];
    
    //KT
    int fac[]={1,1,2,6,24,120,720,5040,40320,362880};
    int KT(int s[]){
        int ans=0,smallNum;
        for(int i=1;i<=n;i++){
            smallNum=0;
            for(int j=i+1;j<=n;j++){
                if(s[i]>s[j])smallNum++;
            }
            ans+=smallNum*fac[n-i];
        }
        return ans;
    }
    void InvKT(int k,int s[]){
        int t,j;
        bool v[11]; memset(v,false,sizeof(v));
        for(int i=1;i<=n;i++){
            t=k/fac[n-i];
            for(j=1;j<=n;j++){
                if(v[j]==false){
                    if(t==0)break;
                    else t--;
                }
            }
            s[i]=j; v[j]=true;
            k%=fac[n-i];
        }
    }
    
    //零件
    bool isWin(Node k){
        for(int i=1;i<=3;i++){
            for(int j=1;j<=3;j++){
                if(k.board[i][j]!=end[(i-1)*3+j])return false;
            }
        }
        return true;
    } 
    bool vis(Node k){
        int s[11];
        for(int i=1;i<=3;i++){
            for(int j=1;j<=3;j++){
                s[(i-1)*3+j]=k.board[i][j];
            }
        }
        int num=KT(s);
        if(visited[num]==true)return true;
        else{ visited[num]=true; return false; }
    }
    bool check(Point p){
        if(p.x>=1&&p.y>=1&&p.x<=3&&p.y<=3)return true;
        else return false;
    }
    void swapBoard(Node& k,Point a,Point b){
        int temp=k.board[a.x][a.y];
        k.board[a.x][a.y]=k.board[b.x][b.y];
        k.board[b.x][b.y]=temp;
    }
    void outPut(Node a){
        cout<<"This is a Node:"<<endl;
        for(int i=1;i<=3;i++){
            for(int j=1;j<=3;j++){
                cout<<a.board[i][j]<<' ';
            }
            cout<<endl;
        }
        cout<<"Space: "<<a.space.x<<' '<<a.space.y<<endl;
        cout<<"Step: "<<a.step<<endl;
        
        flag++;
        if(flag>10)exit(0);
    }
    
    //Bfs
    int bfs(Node start){
        memset(visited,false,sizeof(visited));
        queue<Node> q;
        q.push(start);
        vis(start);
        
        while(!q.empty()){
            Node k=q.front(); q.pop();
            //outPut(k);
            for(int i=0;i<4;i++){
                Point newSpace=k.space; newSpace.x+=dx[i]; newSpace.y+=dy[i];
                if(check(newSpace)){
                    Node t=k;
                    swapBoard(t,t.space,newSpace);
                    t.space=newSpace; t.step++;
                    if(isWin(t))return t.step;
                    if(!vis(t))q.push(t);
                }
            }
        }
        return -1;
    }
    
    //Main
    int main(){
        freopen("1225.in","r",stdin);
        
        char cc; Node start;
        for(int i=1;i<=3;i++){
            for(int j=1;j<=3;j++){
                cin>>cc;
                if(cc=='0'){
                    start.board[i][j]=9;
                    start.space.x=i; start.space.y=j;
                }
                else start.board[i][j]=cc-'0';
            }
        } 
        start.step=0;
        cout<<bfs(start)<<endl;
        
        fclose(stdin);
        return 0;
    }

    测试点#1.in 结果: 内存使用量: 488kB 时间使用量: 1ms 
    测试点#2.in 结果: 内存使用量: 1128kB 时间使用量: 3ms 
    测试点#3.in 结果: 内存使用量: 1128kB 时间使用量: 6ms 
    测试点#4.in 结果: 内存使用量: 620kB 时间使用量: 2ms 
    测试点#5.in 结果: 内存使用量: 748kB 时间使用量: 1ms 

    2.把棋盘的康拓作为状态(为A*做准备):

    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<cstdlib>
    using namespace std;
    
    const int n=9;
    const int Size=4;
    int flag;
    struct Point{
        int x,y;
    };
    int end[]={0, 1,2,3,8,9,4,7,6,5};
    int KTend=-1;
    int dx[4]={-1,0,1,0}; int dy[4]={0,1,0,-1};
    bool visited[400005];
    int f[400005],step[400005],h[400005];
    
    //KT
    int fac[]={1,1,2,6,24,120,720,5040,40320,362880};
    int KT(int s[]){
        int ans=0,smallNum;
        for(int i=1;i<=n;i++){
            smallNum=0;
            for(int j=i+1;j<=n;j++){
                if(s[i]>s[j])smallNum++;
            }
            ans+=smallNum*fac[n-i];
        }
        return ans;
    }
    int KT(int s[Size][Size]){
        int a[11];
        for(int i=1;i<=3;i++){
            for(int j=1;j<=3;j++){
                a[(i-1)*3+j]=s[i][j];
            }
        }
        return KT(a);
    }
    void InvKT(int k,int s[]){
        int t,j;
        bool v[11]; memset(v,false,sizeof(v));
        for(int i=1;i<=n;i++){
            t=k/fac[n-i];
            for(j=1;j<=n;j++){
                if(v[j]==false){
                    if(t==0)break;
                    else t--;
                }
            }
            s[i]=j; v[j]=true;
            k%=fac[n-i];
        }
    }
    void InvKT(int k,int s[Size][Size]){
        int a[11];
        InvKT(k,a);
        for(int i=1;i<=3;i++){
            for(int j=1;j<=3;j++){
                s[i][j]=a[(i-1)*3+j];
            }
        }
    }
    
    //零件
    bool isWin(int kt){
        if(KTend==-1)KTend=KT(end);
        return KTend==kt;
    } 
    bool vis(int kt){
        if(visited[kt]==true)return true;
        else{ visited[kt]=true; return false; }
    }
    bool check(Point p){
        if(p.x>=1&&p.y>=1&&p.x<=3&&p.y<=3)return true;
        else return false;
    }
    void swapBoard(int board[Size][Size],Point a,Point b){
        int temp=board[a.x][a.y];
        board[a.x][a.y]=board[b.x][b.y];
        board[b.x][b.y]=temp;
    }
    Point getSpacePoint(int board[Size][Size]){
        Point p;
        for(int i=1;i<=3;i++){
            for(int j=1;j<=3;j++){
                if(board[i][j]==9){
                    p.x=i; p.y=j;
                    break;
                }
            }
        }
        return p;
    }
    void copy(int a[Size][Size],int b[Size][Size]){
        for(int i=1;i<=3;i++){
            for(int j=1;j<=3;j++){
                b[i][j]=a[i][j];
            }
        }
    }
    
    
    //Bfs
    int bfs(int start){
        memset(visited,false,sizeof(visited));
        queue<int> q;
        q.push(start);
        vis(start);
        step[start]=0;
        
        while(!q.empty()){
            int kt=q.front(); q.pop();
            int s[Size][Size]; InvKT(kt,s);
            Point space=getSpacePoint(s);
            for(int i=0;i<4;i++){
                Point space2=space; space2.x+=dx[i]; space2.y+=dy[i];
                if(check(space2)){
                    int s2[Size][Size]; copy(s,s2);
                    swapBoard(s2,space,space2);
                    int kt2=KT(s2); step[kt2]=step[kt]+1;
                    if(isWin(kt2))return step[kt2];
                    if(!vis(kt2))q.push(kt2);
                }
            }
        }
        return -1;
    }
    
    //Main
    int main(){
        freopen("1225.in","r",stdin);
        
        char cc; int start[11];
        for(int i=1;i<=n;i++){
            cin>>cc;
            if(cc=='0')start[i]=9;
            else start[i]=cc-'0';
        } 
        int KTstart=KT(start);
        cout<<bfs(KTstart)<<endl;
        
        fclose(stdin);
        return 0;
    }
    测试点#1.in  结果:    内存使用量:  620kB     时间使用量:  1ms     
    测试点#2.in 结果: 内存使用量: 2024kB 时间使用量: 8ms
    测试点#3.in 结果: 内存使用量: 2028kB 时间使用量: 6ms
    测试点#4.in 结果: 内存使用量: 1772kB 时间使用量: 2ms
    测试点#5.in 结果: 内存使用量: 1772kB 时间使用量: 3ms

  • 相关阅读:
    动态传参
    函数的介绍
    文件的操作
    send email with formatted table
    minimize and close window with customed winform
    python algorithm
    something important about docker
    book list
    which language is suitable for what to do
    Find Duplicate Items in list fast
  • 原文地址:https://www.cnblogs.com/FuTaimeng/p/5602957.html
Copyright © 2011-2022 走看看