您的位置:首页 > 其它

八数码第一境界——暴力反向BFS+存状态

2017-12-13 01:42 288 查看
这题首先会遇到一个问题:BFS无法实施

为什么会无法实施?



正常情况,x从队列中取出,8、6入队

8从队列中取出,x和8交换,7、5入队

这个时候下一个要出队列的是6,但是你x在8原来的位置,怎么实施交换?

所以队列中应该入的是状态,可能很抽象,但是下面的图不抽象。



我们还是看6要出队列的时候的情况,就是第三行第一个。我们发现他可以出队列了。出队列,向左移动的一个情况以及向右移动的一个情况被添加到队列底端。

如何存这个队列?

采用结构体。

struct node  

{  

    string str;  

    vector<int>res;  

    int index;  

};  

map<string,int> mp;  

vector<int>res;
 

str一维数组,把二维数组降了一维。

vector用来存你历次的移动方向。

index用来存当前str中的x在哪个位置。

map用来判断当前这种状态我们是否已经走过了。

具体BFS的方法?

while(!q.empty())  

    {  

        g=q.front();q.pop();  

        if(g.str==ss)  

        {  

            res=g.res;  

            return true;  

        }  

        h=g;  

        if((h.index+1)%3!=0)  

        {  

            c=h.str[h.index];h.str[h.index]=h.str[h.index+1];h.str[h.index+1]=c;  

            h.index++;  

            h.res.push_back(4);  

            if(mp[h.str]==0)  

            {  

                mp[h.str]=true;  

                q.push(h);  

            }  

        }  

第三行,出队列。

接下来的if判断,用来判断是否当前这个状态和我们要求的一样,如果是,那代表已经找到了,返回true。

h=g,把当前队首元素给h,因为当前的队首元素后面还要用,这里仅仅是代表了他右移的可能性。

接下来if判断,如果他不是最后一列,我们进入这个if,而且不用想在不是最后一列的情况下我们是可以右移的。

和右边的数交换。

x所在string中的位置增加一位。

4存入操作,4代表的是右移。

如果这种状态的键取出来的值是0,那就代表这种状态以前没走过,可以入队列,并且把这个状态设置为已走过。

完毕。

接下来几个方向也是几乎一样的操作。

全部代码

char s[101];  

struct node  

{  

    string str;  

    vector<int>res;  

    int index;  

};  

map<string,int> mp;  

vector<int>res;  

  

bool bfs(string ss)  

{  

    char c;  

    queue<node> q;  

    while(!q.empty())q.pop();  

    node g,h;  

    g.str="12345678x";g.res.clear();g.index=8;  

    q.push(g);  

    while(!q.empty())  

    {  

        g=q.front();q.pop();  

        if(g.str==ss)  

        {  

            res=g.res;  

            return true;  

        }  

        h=g;  

        if((h.index+1)%3!=0)  

        {  

            c=h.str[h.index];h.str[h.index]=h.str[h.index+1];h.str[h.index+1]=c;  

            h.index++;  

            h.res.push_back(4);  

            if(mp[h.str]==0)  

            {  

                mp[h.str]=true;  

                q.push(h);  

            }  

        }  

        h=g;  

        if(h.index%3!=0)  

        {  

            c=h.str[h.index];h.str[h.index]=h.str[h.index-1];h.str[h.index-1]=c;  

            h.index--;  

            h.res.push_back(3);  

            if(!mp[h.str])  

            {  

                mp[h.str]=true;  

                q.push(h);  

            }  

        }  

        h=g;  

        if(h.index<6)  

        {  

            c=h.str[h.index];h.str[h.index]=h.str[h.index+3];h.str[h.index+3]=c;  

            h.index+=3;  

            h.res.push_back(2);  

            if(!mp[h.str])  

            {  

                mp[h.str]=true;  

                q.push(h);  

            }  

        }  

        h=g;  

        if(h.index>2)  

        {  

            c=h.str[h.index];h.str[h.index]=h.str[h.index-3];h.str[h.index-3]=c;  

            h.index-=3;  

            h.res.push_back(1);  

            if(!mp[h.str])  

            {  

                mp[h.str]=true;  

                q.push(h);  

            }  

        }  

    }  

    return false;  

}  

int main()  

{  

    int i,j,k,kk,t,x,y,z;  

    while(scanf("%s",s)!=EOF)  

    {  

        mp.clear();  

        for(i=1;i<9;i++)  

            scanf("%s",s+i);  

        string ss(s);  

        if(bfs(ss))  

            for(i=res.size()-1;i>=0;i--)  

            {  

                if(res[i]==1)printf("d");  

                if(res[i]==2)printf("u");  

                if(res[i]==3)printf("r");  

                if(res[i]==4)printf("l");  

            }  

        else  

            printf("unsolvable");  

        printf("\n");  

    }  

    return 0;  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: