八数码第一境界——暴力反向BFS+存状态
这题首先会遇到一个问题: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;
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;
- }