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

浙公网安备 33010602011771号