持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情
八数码难题
题目描述
在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。
输入格式
输入初始状态,一行九个数字,空格用0表示
输出格式
只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)
样例 #1
样例输入 #1
283104765
样例输出 #1
4
分析:这是个比较隐晦的,把一个字符串分成三行,然后跟迷宫一个驾驶,然后每个状态记录一下用,最后在输出一下mp[se];
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <stack>
#include <cmath>
#include <iomanip>
#define ll long long
#define AC return
#define Please 0
using namespace std;
const int N=510;
const double esp=1e-8;
typedef pair<int,int>PII;
typedef unsigned long long ull;
map<string, pair<char, string>> pre;
unordered_map<string,int>mp;
inline int read(){//快读
int x=0,f=1;char ch=getchar();
while(ch<'0' || ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
AC x*f;
}
int dx[4]={0,0,-1,1};
int dy[4]={1,-1,0,0};
bool check(int x,int y){
return (x>=0 && x<=2 && y>=0 && y<=2);
}
string en;
int bfs(string x){
mp.clear();
en="123804765";
queue<string> q;
q.push(x);
mp[x]=0;
while(q.size()){
string t=q.front();
int d=mp[t];
q.pop();
int loc=t.find('0');
int sx=loc/3,sy=loc%3;
for(int i=0;i<4;i++){
int nex=sx+dx[i],ney=sy+dy[i];
if(check(nex,ney)){
swap(t[nex*3+ney],t[loc]);
if(!mp.count(t)){
//cout<<now<<endl;
mp[t]=d+1;
//cout<<mp[now]<<" ";
q.push(t);
}
swap(t[nex*3+ney],t[loc]);
}
}
}
}
int n,m,p,cnt=0;
int main(){
string s;
cin>>s;
bfs(s);
cout<<mp[en];
}
希望能帮助到大家()!