2007百度之星总决赛试题八方块移动的简单算法
来源:互联网 发布:淘宝人群导购 编辑:程序博客网 时间:2024/05/01 17:56
八方块移动游戏要求从一个含8个数字(用1-8表示)的方块以及一个空格方块(用0表示)的3x3矩阵的起始状态开始,
不断移动该空格方块以使其和相邻的方块互换,直至达到所定义的目标状态。
空格方块在中间位置时有上、下、左、右4个方向可移动,在四个角落上有2个方向可移动,在其它位置上有3个方向可移动。
例如,假设一个3x3矩阵的初始状态为:
8 0 3
2 1 4
7 6 5
要求的目标状态为:
1 2 3
8 0 4
7 6 5
则一个合法的移动路径为:
8 0 3 8 1 3 8 1 3 0 1 3 1 0 3 1 2 3
2 1 4 => 2 0 4 => 0 2 4 => 8 2 4 => 8 2 4 => 8 0 4
7 6 5 7 6 5 7 6 5 7 6 5 7 6 5 7 6 5
另外,在所用可能的从初始状态到目标状态的移动路径中,步数最少的路径被称为最短路径;
在上面的例子中,最短路径为5。如果不存在从初始状态到目标状态的任何路径,则称该组状态无解。
请设计算法找到从八方块的某初始状态到某目标状态的所有可能路径的最短路径
- #define WIN32_LEAN_AND_MEAN
- #define _CRT_SECURE_NO_DEPRECATE
- #include <iostream>
- #include <map>
- #include <queue>
- #include <cstring>
- #include <ctime>
- #include <cassert>
- const unsigned int strLength = 9;
- using namespace std;
- // 交换字符串src中 x和y的值,返回被交换后的新串
- char* swap(char* src, int x, int y)
- {
- assert(strlen(src)==strLength);
- char* dest = new char[strLength+1];
- strcpy(dest, src);
- char temp = dest[x];
- dest[x] = dest[y];
- dest[y] = temp;
- return dest;
- }
- //为Map<char*,char*>提供的比较函数.用于比较字符串值,取代默认的比较字符串地址
- struct ltstr
- {
- bool operator()(const char* s1, const char* s2) const
- {
- return strcmp(s1, s2) < 0;
- }
- };
- //核心算法,start为初始状态 goal为目标状态
- //没有使用A* 算法 或启发式寻找 我在这个题目中,我找不到这样的启发条件.
- //我觉的启发式并不一定能得到最优解 这题明确要求是最短路径
- //用队来实现广度优先 用map来保存所有节点.实现图的效果 map中每项数据由<节点,节点的父节点>构成
- //返回值为两种状态需要的最短步数.
- int FindStep(char* start, char* goal)
- {
- assert(strlen(start)==strLength);
- assert(strlen(goal)==strLength);
- map<char*, char*, ltstr> strMap;
- map<char*, char*,ltstr>::iterator iter;
- queue<char*> strQueue;
- strQueue.push(start);
- unsigned int step = 0;
- while (!strQueue.empty())
- {
- char* str = strQueue.front();
- strQueue.pop();
- //确定节点中字符'0'所在的位置
- unsigned int pos;
- for (pos = 0; pos < strLength && str[pos] != '0'; pos++);
- //由当前结点移位得到4个新的子结点的指针数组初始为NULL
- char* generate[4];
- for (int i = 0; i < 4; i++)
- generate[i] = NULL;
- //当前节点左移 右移 上移 下移 并生成新节点
- if ((pos % 3) != 0) generate[0] = swap(str, pos, pos - 1);
- if ((pos % 3) != 2) generate[1] = swap(str, pos, pos + 1);
- if (pos > 2) generate[2] = swap(str, pos, pos - 3);
- if (pos < 6) generate[3] = swap(str, pos, pos + 3);
- //处理生成的四个新节点
- for (int i = 0; i < 4; i++)
- {
- if (generate[i] == NULL)
- continue;
- //如果此结点图中(Map中)已存在,删除此结点 并返回
- if (strMap.find(generate[i]) != strMap.end())
- {
- delete generate[i];
- continue;
- }
- //如果此结点不是目标状态节点则入队,并将此节点加入图中
- if (strcmp(generate[i], goal) != 0)
- {
- strQueue.push(generate[i]);
- strMap.insert(make_pair(generate[i], str));
- continue;
- }
- strMap.insert(make_pair(generate[i], str));
- char *back = generate[i];
- //执行到这里则说明此结点为目标状态结点遁环查找其父结点
- while (strcmp(back, start) != 0)
- {
- step++;
- back = (strMap.find(back))->second;
- cout << back << "/n";
- }
- //释放内存 并返回步数;
- for (iter = strMap.begin(); iter != strMap.end(); iter++)
- delete iter->first;
- return step;
- }
- }
- //目标状态不可到达 释放内存 返回-1;
- for (iter = strMap.begin(); iter != strMap.end(); iter++)
- delete iter->first;
- return -1;
- }
- int main()
- {
- //char* start = "803214765";
- char* start = "784356102";
- char* goal = "123804765";
- //char* goal = "012345678";
- cout << "开始寻找..." << endl;
- clock_t startTime = clock();
- cout << "需要 " << FindStep(start, goal) << " 步.(如果为-1则目标状态不可到达) /n";
- cout << "共用时" << (clock() - startTime) << "毫秒.(关闭FindStep函数中的cout输出可以更快点) "<<endl;
- system("PAUSE");
- return 0;
- }
- 2007百度之星总决赛试题八方块移动的简单算法
- php解: 2005年百度之星程序设计大赛试题总决赛题目 ------八方块移动游戏
- 2005年百度之星程序设计大赛试题复赛的解答(八方块移动游戏)
- 2005年百度之星程序设计大赛试题总决赛题目---第一次发博客
- 简单的八方向寻路算法
- AStar2006百度之星程序设计大赛决赛试题
- 2005“百度之星”程序设计大赛网上决赛试题
- CBA总决赛之气死人的网络直播
- 百度之星2005决赛题目
- 2006年百度之星决赛题目
- 2006年百度之星决赛题目
- 记2017年百度之星决赛
- HDU 6113 度度熊的01世界【2017"百度之星"】【简单搜索判断联通块】
- 2005年第29届ACM ICPC世界总决赛的试题解析
- 2007年ACM国际大学生程序设计竞赛总决赛试题A:同血亲血型计算
- 2007年ACM国际大学生程序设计竞赛总决赛试题B,C
- 创新中国总决赛之行
- 计蒜之道2016 总决赛
- Fedora 9 安装手册
- C++中extern “C”含义深层探索
- 看这里看这里看这里
- jsp文件与htm文件的tiles布局乱码
- 软件开发招聘怪论
- 2007百度之星总决赛试题八方块移动的简单算法
- msn 协议 命令
- VC中AnimateWindow函数用法(窗口的淡入淡出)
- C#对于文件操作
- C#收集网页中的EMail实现源码
- vim用户手册
- 站在分岔路上
- c#采集网页用得几个函数 有解释
- 07-5-3:学点思科防火墙配置