NPU17届程序设计 1571 八数码问题 暴力BFS

来源:互联网 发布:mac磁盘工具可清除 编辑:程序博客网 时间:2024/06/07 07:20

Problem I

八数码

时限:5000ms 内存限制:20000K 总时限:10000ms

描述:

在九宫格里放在1到8共8个数字还有一个是空格,与空格相邻的数字可以移动到空格的位置,问给定的状态最少需要几步能到达目标状态(用0表示空格):
1 2 3
4 5 6
7 8 0

输入:

输入一个给定的状态。

输出:

输出到达目标状态的最小步数。不能到达时输出-1。

输入样例:

1 2 34 0 67 5 8

输出样例:

2

本题依旧可以使用一个变量将当前状态的八数码地图储存起来,使用队列储存地图,使用map函数的功能标记当前状态地图是否已经生成过,记录到达当前状态所需最小步数。这里还是运用了暴力的广搜法。本题主要难点依旧是如何储存八数码地图,标记当前地图。这里使用了C++的容器,不得不说,C++功能真的强大。

#include<iostream>#include<queue>#include<map>using namespace std;queue<int> q;//储存当前八数码的数据 map<int,int> used;//一一对应记录该情况是否已经出现过 map<int,int> step;//一一对应记录达到该情况所需最小步数 int oldmap[3][3];int num;int crow,ccol;//0所在的行,列 //方向0为向右换,1为向下换,2为向左换,3为向上换; int dr[4] = {0,1,0,-1};int dc[4] = {1,0,-1,0};void init();int bfs();void readdata();int oldmaptonum();void numtooldmap(int cnum);int canmoveto(int u,int i);int moveto(int u,int i);int main(){int result;readdata();init();result = bfs();cout << result << endl;} void init(){//初始化数据,将初始地图转化为数字并加入队列 num = oldmaptonum();step[num] = 0;q.push(num);used[num] = 1; }void readdata(){int i,j;for (i=0;i<3;i++){for (j=0;j<3;j++){cin >> oldmap[i][j];}}}int bfs(){int u,v,i;while (!q.empty()){u = q.front();q.pop();for (i=0;i<4;i++){if (canmoveto(u,i)){ v = moveto(u,i);if (v == 123456780){return (step[u] + 1);}else if (used[v] != 1){q.push(v);used[v] = 1;step[v] = step[u] + 1; }}}}return (-1);}int oldmaptonum(){//地图变换为数字储存 int i,j,cnum;cnum = 0;for (i=0;i<3;i++){for (j=0;j<3;j++){cnum = cnum*10;cnum = cnum + oldmap[i][j];}}return (cnum);}void numtooldmap(int cnum){//数字变换为地图 int i,j;for (i=2;i>=0;i--){for (j=2;j>=0;j--){oldmap[i][j] = cnum % 10;cnum = cnum / 10;if (oldmap[i][j] == 0){crow = i;ccol = j;}}}}int canmoveto(int u,int i){//判断当前交换的方向是否合法 int nrow,ncol;numtooldmap(u);nrow = crow + dr[i];ncol = ccol + dc[i];if (nrow<0 || nrow>2 || ncol>2 || ncol<0) {//如果越界返回0,没有则返回1 return (0);}else{ return (1);}}int moveto(int u,int i){//将0与新位置的数交换 int savenum,nrow,ncol;nrow = crow + dr[i];ncol = ccol + dc[i];savenum = oldmap[nrow][ncol];oldmap[nrow][ncol] = 0;oldmap[crow][ccol] = savenum;savenum = oldmaptonum();return (savenum);}

原创粉丝点击