您的位置:首页 > 其它

八数码难题(BFS)(队列)

2017-01-23 14:11 337 查看

1288: 八数码难题

时间限制: 1 Sec 内存限制: 128 MB
提交: 39 解决: 9
[提交][状态][讨论版]

题目描述

在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(目标状态),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。

输入

包含六行,每行三个数字,数字之间用空格间隔。前三行为初始状态,后三行为目标状态。

输出

只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数。如果无法从初始状态得到目标状态,或移动步数超过25还不能得到目标状态,则输出“No solution!”。

样例输入

2 8 3
1 6 4
7 0 5
1 2 3
8 0 4
7 6 5

样例输出

5

提示

对50%的数据, 移动步数不超过10次;

对其余50%的数据, 需超过10次移动才能达到目标状态,或在20步内不能达到目标状态;

来源

#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
const int data[5]={0,-3,-1,1,3};
map<string,bool> h;
int xy[160001],total[160001];
string s[160001],k,e;
char c;
string swap(int i,int j,string s){
string p; char c;
p=s;
c=p[i]; p[i]=p[j]; p[j]=c;
return p;
}
void doit(int x,string k){
int tail=1,head=0,m;
string l;
xy[1]=x; s[1]=k; h[k]=1;
while(tail>head){
head++;
for(int i=1;i<=4;i++){
m=xy[head]+data[i];
if((m==2&&xy[head]==3)||(m==3&&xy[head]==2)||
(m==5&&xy[head]==6)||(m==6&&xy[head]==5)) continue;
if(m>=0&&m<9){
l=swap(xy[head],m,s[head]);
if(h[l]==0){
tail++; if(tail>160000) tail=1;
h[l]=1; xy[tail]=m;
s[tail]=l;
total[tail]=total[head]+1;
//cout<<s[tail]<<endl;
if(l==e){
cout<<total[tail]<<endl; /*print(tail);*/ return;
}
if(total[tail]>25){
cout<<"No solution!"; return;
}
}
}
}
}
}
int main(){
for(int i=1;i<=9;i++) {
cin>>c; k+=c;
}
for(int i=1;i<=9;i++) {
cin>>c; e+=c;
}
if(k==e){
cout<<0; return 0;
}
for(int i=0;i<k.size();i++) if(k[i]=='0') {
doit(i,k); break;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: