马的遍历
来源:互联网 发布:网络十大丑男恶搞图片 编辑:程序博客网 时间:2024/04/29 20:44
问题描述:
国际象棋或中国象棋中,在棋盘上,从任意指定的方格出发,为马寻找一条路径使马能走遍棋盘每一格并且每格只经过一次。
分析:
如果是使用深度优先搜索+回溯,时间复杂度高,这里我们需要一种更高效的算法。使用贪心的思想,在每个结点对其子结点进行选取时,优先选择子节点可落子位置最少的结点。可落子位置意思是下一步能走到得位置,如:
马口口口口
口口口口口
口口口口口
口口口口口
它的可落子位置为2。
/*马的遍历*/#include <cstdio>#include <cstring>#include <vector>#include <iostream>using namespace std;class Pos{public: int x; int y; Pos(int x, int y):x(x),y(y){}};vector<Pos> store; //用于存储路径//棋盘数据:const int WIDTH = 9; //棋盘宽和高const int HEIGHT = 10;int board[WIDTH+1][HEIGHT+1]; //棋盘数组保存数据为每个位置对应马的路线的第几步//dir为马的八个方向const int dir[8][2] = {{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2}};//求(i,j)位置的出口,并返回所有出口和对应的出口个数int exitn(int i,int j,int s,int a[]){int k,i1,j1;int count; //计数出口的个数for (count=k=0; k<8; k++){i1 = i + dir[(s+k)%8][0]; //八方向横坐标和纵坐标,(s+k)%8让索引保持在八方向上j1 = j + dir[(s+k)%8][1];if(i1>=0 && i1<HEIGHT && j1>=0 && j1<WIDTH && board[i1][j1]==0) //在棋盘的范围内并且没有走过a[count++]=(s+k)%8;}return count;}//将(i,j)节点以s开始的下一个节点序列中,节点数最小的一个返回int next(int i,int j,int s){int m,k,go,min,a[8],b[8],temp;m = exitn(i, j, s, a); //当前位置有出口数if(m==0) //没有 return -1;for(min=8,k=0; k<m; k++) //搜寻出口最少的位置{temp = exitn(i+dir[a[k]][0], j+dir[a[k]][1], s, b);if(temp < min) //保存最小出口{min = temp;go = a[k]; //保存方向索引}}return go; //返回最少出口位置的方向索引}int main(int argc, char* argv[]){ cout << " ----------------中国象棋中马的遍历----------------- \n"<< endl;int istartX(0), istartY(0); //表示当前起始位置while (1){ cout << "请输入马的起始位置行号(0~9):"; cin >> istartX; if (istartX >= 0 && istartX <= 9) break;} while (1) { cout << "请输入马的起始位置列号(0~8):"; cin >> istartY; if (istartY >= 0 && istartY <= 8) break; } int step, flag, start=1; //step表示第几步,flag标记下一步的方向,start表示方向索引的初始值memset(board,0,sizeof(int)*WIDTH*HEIGHT); //初始化棋盘,0表示没有走过board[istartX][istartY]=1; //起始位置的第一步,1表示第一步,N表示第N步 Pos v(istartX, istartY); store.push_back(v); cout << "\n棋盘中的轨迹:(数字表示第几步,所在位置为棋盘位置)" << endl;for(step=2; step <= WIDTH*HEIGHT; step++) //从第二步开始,直到走满整个棋盘{if ((flag = next(istartX, istartY, start)) == -1) //返回-1,没有找到出口 break;istartX += dir[flag][0]; //下一步的起始坐标istartY += dir[flag][1];board[istartX][istartY] = step; //保存当前步到棋盘作为标记 Pos v(istartX,istartY); store.push_back(v); //将位置坐标存储 } int i, j;for(i=0; i<HEIGHT; i++) //输出棋盘保存的路径{for(j=0; j<WIDTH; j++)printf("%5d", board[i][j]); //5格对齐cout << endl;}int count = 0;cout << "马遍历的路径为:" << endl;for(vector<Pos>::iterator it = store.begin(); it != store.end(); ++it){ cout << "第" << ++count << "步: (" << (*it).x << "," << (*it).y << ")" << endl;}return 0;}
- 图的遍历算法-马遍历棋盘
- 图的遍历算法-马遍历棋盘
- 马的遍历问题
- 马的遍历
- 马的遍历问题
- 马的遍历
- 马的遍历
- 马的遍历
- 马的遍历问题
- 马的遍历
- poj1915 马的遍历
- 马的遍历问题
- 马的遍历问题
- 马的遍历问题
- [BFS]马的遍历
- P1443 马的遍历
- OJ:马的遍历
- 马的遍历
- C语言开发平台editPlus+MinGW(gcc)的建立
- 西游记
- sicily 1172 Queens, Knights and Pawns
- OC和LLVM将得到重大的改进
- 想起你,连呼吸都疼那么,你听得到祝福就好.
- 马的遍历
- 在组合框中显示系统盘符
- Oracle 学习 笔记
- linux下软件安装(未完善)
- android开发环境及java JDK开发环境搭建
- USACO section 3.1 Stamps(dp)
- Fast Colored TextBox for Syntax Highlighting(用于语法高亮的快速着色TextBox)
- 喜欢的歌、静静地听。喜欢的人、远远的看
- Zend framework创建