zoukankan      html  css  js  c++  java
  • BFS()搜索加上hash

    #include<algorithm>
    #include<cstdio>
    #include<iostream>
    #include<queue>
    #include<cstring>
    using namespace std;
    unsigned x;
    unsigned int goal;//最终状态表示的数值 
    const int dx[]={0,0,1,-1};
    const int dy[]={1,-1,0,0};
    int ans = 0;
    int hash[65535+100];
    void print(int a[5][5]);
    unsigned int num(int a[5][5]);
    void copy(int b[5][5],int a[5][5]);
    void num_change(unsigned int x,int a[5][5]);
    
    
    struct Node
    {
        Node(int _level,unsigned int _x):level(_level),x(_x){ }
        int level;
        unsigned int x;
    };
    
    int main(void)
    {
        cin >> x;
        int a[5][5];
        
        int mod = 1;
        for(int i=1;i<=8;i++) 
        {
            goal += mod;
            mod*=2;
        }
        hash[x]=1;
        queue<Node>que;
        Node p = Node(0,x);
        que.push(p);
            
        while(!que.empty())
        {
            Node temp = que.front() ; que.pop();
            if(temp.x == goal)
            {
                ans = temp.level;
                break;
            }
            int b[5][5],next_level = temp.level+1;
            //cout << next_level << endl;
            num_change(temp.x,b);
            for(int i=1;i<=4;i++)
            {
                for(int j=1;j<=4;j++)
                {
                    if(b[i][j])
                    {
                        for(int dir=0;dir<4;dir++)
                        {
                            int newx = i+dx[dir];
                            int newy = j+dy[dir];
                            if(newx>=1 && newx<=4 && newy>=1 && newy<=4 && b[newx][newy]==0)
                            {
                                int c[5][5];
                                copy(c,b);
                                c[i][j]=0;
                                c[newx][newy]=1;
                                if(hash[num(c)]==0)
                                {
                                    p=Node(next_level,num(c));
                                    que.push(p);
                                    hash[num(c)]=1;
                                }
                            }
                        }
                    }
                }    
            }
        }
        cout << ans ; 
        return 0;
    }
    void print(int a[5][5]) 
    {
        for(int i=1;i<=4;i++)
        {
            for(int j=1;j<=4;j++)
            {
                cout << a[i][j] << "  ";
            }
            cout << endl;
        }
    }
    unsigned int num(int a[5][5])
    {
        unsigned int q = 1;
        unsigned int sum = 0;
        for(int i=4;i>=1;i--)
        {
            for(int j=4;j>=1;j--)
            {
                sum += a[i][j]*q;
                q*=2;
            }
        }
        return sum;
    }
    void copy(int b[5][5],int a[5][5])
    {
        for(int i=1;i<=4;i++)
        for(int j=1;j<=4;j++)
         b[i][j]=a[i][j];
    }
    
    void num_change(unsigned int x,int a[5][5])
    {
        unsigned int mod = 2;
        for(int i=4;i>=1;i--)
        {
            for(int j=4;j>=1;j--)
            {
                a[i][j]=x%2;
                x/=2;                
            }    
        } 
    }

     这是一个通用的方法,还可以使用贪心算法:

    可以先将每一列的0全部移动到这一列的上方,然后如果白色的棋子没有刚好形成两行,那么就依次 将移动之后 最下方的白色棋子移动到黑色棋子最高的地方。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int ans[5][5];
    int main(void)
    {
        unsigned int x;
        cin >> x;
        int a[5][5];
        for(int i=4;i>=1;i--)
        {
            for(int j=4;j>=1;j--)
            {
                a[i][j]=x%2;
                x/=2;    
            } 
        } 
        int step = 0;
        for(int j=1;j<=4;j++)
        {
            int sum0=0,pos=0;
            for(int i=1;i<=4;i++)
            {
                if(a[i][j]==0)
                {
                    sum0++;
                    pos+=i;
                    
                }
            }
            if(sum0==1) step+=pos-1,ans[2][j]=ans[3][j]=ans[4][j]=1;
            if(sum0==2) step+=pos-1-2,ans[3][j]=ans[4][j]=1;
            if(sum0==3) step+=pos-1-2-3,ans[4][j]=1;
            if(sum0==4) step+=pos-1-2-3-4;
        }
        bool find = true;
        while(find)
        {
            int x1,y1,x2,y2;
            find = false;
            for(int i=4;i>=3;i--)
            {
                for(int j=4;j>=1;j--)
                {
                    if(ans[i][j]==0)
                    {
                        find = true;
                        x1=i,y1=j;
                        break;
                    }
                }
                if(find) break;
            }
            bool first=false;
            if(find)
            {
                for(int i=1;i<=2;i++)
                {
                    for(int j=4;j>=1;j--)
                    {
                        if(ans[i][j]==1)
                        {
                            first = true;
                            x2=i,y2=j;
                            break;
                        }
                    }
                    if(first) break;
                }
                step+=abs(x1-x2)+abs(y1-y2);
                ans[x1][y1]=1;
                ans[x2][y2]=0;
            }    
        }
        cout << step;
        return 0;
    }
  • 相关阅读:
    自定义Android Toasts风格
    用TAPI实现来电拒接
    压缩与解压缩的实现
    Android之个性化ListView实现
    如何在windows7 Home家庭版中创建Administrator管理员账户
    Android中Intent传递对象的两种方法(Serializable,Parcelable)
    Android模拟器入门
    上海西门子培训第六天(周五)
    上海西门子培训第七天(周六)
    计算机英语学习方法[摘录]
  • 原文地址:https://www.cnblogs.com/zuimeiyujianni/p/9392718.html
Copyright © 2011-2022 走看看