Seven Puzzle Aizu - 0121

Seven Puzzle(反向bfs)

这题和蓝桥杯的一题很像。即将每一种状态用bfs的方式按0的移动方式遍历,就可以得到需要多少步到这个状态。

当然本题的转化过程和方式更加麻烦一些。

同时需要用到反向bfs记录从01234567到各情况所需的步数。(当然这也等同于各情况到01234567所需的步数)

AC代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<algorithm>
#include<cmath>
#include<queue>
#include<string>
#include<map>
#include<sstream>
#define MAXN 500005
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
int w,h,n,cnt=0;
int to[4][2]={1,0, -1,0, 0,-1, 0,1};
string ini="01234567";
map<string,int>vis;
void bfs(){
    queue<string>q;
    q.push("10234567");//先手动将后两个状态输入。 
    q.push("41230567");
    vis["10234567"]=1;
    vis["41230567"]=1;
    while(!q.empty()){
        string u=q.front();
        q.pop();
        for(int i=0;i<8;i++){
            if(u[i]=='0'){//查找0的位置 
                if(i==0||i==4||i==3||i==7){//如果在四角,则0只能向2个方向移动 
                    string v=u;
                    v[i]=v[(i+4)%8];
                    v[(i+4)%8]='0';
                    if(!vis[v]){
                        vis[v]=vis[u]+1;
                        q.push(v); 
                    }
                    v=u;
                    int temp;
                    if(i==0||i==4)
                        temp=i+1;
                    else
                        temp=i-1;
                    v[i]=v[temp];
                    v[temp]='0';
                    if(!vis[v]){
                        vis[v]=vis[u]+1;
                        q.push(v);
                    }
                }else{//不在四个角,那么能向3个方向移动 
                    string v=u;
                    v[i]=v[(i+4)%8];
                    v[(i+4)%8]='0';
                    if(!vis[v]){
                        vis[v]=vis[u]+1;
                        q.push(v);
                    }
                    v=u;
                    v[i]=v[i+1];
                    v[i+1]='0';
                    if(!vis[v]){
                        vis[v]=vis[u]+1;
                        q.push(v);
                    }
                    v=u;
                    v[i]=v[i-1];
                    v[i-1]='0';
                    if(!vis[v]){
                        vis[v]=vis[u]+1;
                        q.push(v);
                    }
                }
            }
            break; 
        }
    }
}
int main(){
    vis[ini]=-1;//先赋为-1防止bfs中重新赋值导致误差 
    bfs();
    vis[ini]=0;
    string ans="";
    int n;
    stringstream ss;//只想到了这个来实现让数字添加到ans后面…… 
    while(~scanf("%d",&n)){
        char temp;
        ss<<n;
        ss>>temp;
        ans+=temp;
        if(vis[ans]||ans==ini){//查找第几步 
            printf("%d\n",vis[ans]);
            ans="";
        }
    }
}

 

posted @ 2021-04-09 21:39  mikku  阅读(65)  评论(0)    收藏  举报