您的位置:首页 > 其它

简单的八数码问题(BFS)

2017-07-28 15:44 309 查看


问题 A: 八数码

时间限制: 1 Sec  内存限制: 256 MB
提交: 9  解决: 7

[提交][状态][讨论版]


题目描述

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


输入

输入初试状态,一行九个数字,空格用0表示


输出

只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊
4000
无法到达目标状态数据)。


样例输入

283104765


样例输出

4


提示

//
// main.cpp
// 问题 A: 八数码
//
// Created by wenhan on 2017/7/28.
// Copyright © 2017年 wenhan. All rights reserved.
//

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <vector>
#include <map>
#include <algorithm>
int s=0;
struct me{
int c[4][4];
int cur;
int x,y;
}me;
int v[4][4]={{0,0,0,0},{0,1,2,3},{0,8,0,4},{0,7,6,5}};
int t[4][4];
using namespace std;
bool panduan(struct me a)
{
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
if(a.c[i][j]!=v[i][j])
return false;
return true;
}
void bfs()
{
if(panduan(me))
return;
queue<struct me>my;
map<long long,int>mx;
my.push(me);
while (!my.empty()) {
struct me x=my.front();
my.pop();
int ss=0;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
ss=ss*10+x.c[i][j];
if(mx.count(ss))
continue;
if(panduan(x))
{
me.cur=x.cur;
return;
}
mx[ss]=1;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
if(x.c[i][j]==0)
{
x.x=i;x.y=j;
break;
}
//printf("%d\n",x.cur);
//接下来是4个方向,我人傻,大神请勿喷
if(x.x+1<=3)
{
struct me y;
y=x;
swap(y.c[y.x][y.y], y.c[y.x+1][y.y]);
y.cur++;
my.push(y);
}
if(x.x-1>=1)
{
struct me y;
y=x;
swap(y.c[y.x][y.y], y.c[y.x-1][y.y]);
y.cur++;
my.push(y);
}
if(x.y+1<=3)
{
struct me y;
y=x;
swap(y.c[y.x][y.y], y.c[y.x][y.y+1]);
y.cur++;
my.push(y);
}
if(x.y-1>=1)
{
struct me y;
y=x;
swap(y.c[y.x][y.y], y.c[y.x][y.y-1]);
y.cur++;
my.push(y);
}
}

}
int main() {
char a[11];
scanf("%s",a);
for(int i=1;i<=3;i++)
for (int j=1; j<=3; j++) {
me.c[i][j]=a[s++]-'0';
}
me.cur=0;
s=0;
bfs();
printf("%d\n",me.cur);
// insert code here...
//std::cout << "Hello, World!\n";
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: