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;
}

 

posted @ 2018-07-30 21:04  最美遇见你  阅读(201)  评论(0编辑  收藏  举报