跳马问题
2016-05-26 09:01
323 查看
1. 跳马问题。要求在64个国际象棋格子,任意位置放一个马,如何不重复地把格子走完。(3)
////////////////////////////////////////////////////// /* 马(N):每步棋先横走或直走一格,然后再往外斜走一格;或者先斜走一格 ,最后再往外横走或竖走一格(即走“日”字)。可以越子,没有"中国象棋 "的"蹩马腿"限制。 */ #include<iostream> #include<queue> #include<stdio.h> #include<string.h> #include "queue.h" using namespace std; #define MAXN 8 const int MaxQueueSize=64; struct point { int x;//马的x方向 int y;//马的y方向 }; typedef struct Queue{ struct point queue[MaxQueueSize]; int front;//头指针 int rear;//尾指针 int tag;//设置标记位 }SeqCQueue; //初始化队列操作 void QueueInitiate(SeqCQueue *Q){ Q->front=0; Q->rear=0; Q->tag=0; } //判断队列是否为空 int QueueNotEmpty(SeqCQueue Q){ if(Q.front==Q.rear&&Q.tag==0) return 0; else return 1; } //入队操作 void QueueAppend(SeqCQueue *Q,point x){ if(Q->tag==1&&Q->front==Q->rear){ printf("队列已满,无法插入!\n"); }else { Q->queue[Q->rear]=x; Q->rear=(Q->rear+1)%MaxQueueSize; Q->tag=1; } } //出队操作 void QueuePop(SeqCQueue *Q,point *d){ if(Q->tag==0&&Q->front==Q->rear){ printf("队列已空,无元素可以出队列!\n"); }else { *d=Q->queue[Q->front]; Q->front=(Q->front+1)%MaxQueueSize; Q->tag=0; } } SeqCQueue Q; int m,n; int step;//记录马走的步数 int map[MAXN][MAXN];//8*8的国际象棋棋盘 int dir[8][2]={{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}};//马理论上所能走全部的位置 //求出该位置的马所能走的步数 int _step(int x,int y){ int i,xi,yi; int count=0; for( i=0;i<8;i++){ xi=x+dir[i][0]; yi=y+dir[i][1]; //边界条件以及!map[xi][yi]表示未走过的位置 if(xi>=0&&xi<=MAXN-1&&yi>=0&&yi<=MAXN-1&&!map[xi][yi]) count++; } return count; } int BFS(point s) { int i,x,y,temp; QueueInitiate(&Q);//初始化队列 QueueAppend(&Q,s);//入队操作 point hd ; int flag=0 ; //当队列非空时,进行广度优先搜索 while(QueueNotEmpty(Q)) { QueuePop(&Q,&hd);//出队列 map[hd.x][hd.y]=step++;//标记该位置已走过 printf("%d,%d\n",hd.x,hd.y);//输出走过的位置 int minstep=10;//初始的最小步数 int flag=0;//标记 //8个方向进行搜索 for( i=0;i<8;i++){ x=hd.x+dir[i][0]; y=hd.y+dir[i][1]; if(x>=0&&x<=MAXN-1&&y>=0&&y<=MAXN-1&&!map[x][y]){ //如果小于当前的最小步数,则让队列元素出队列,并让当前的元素入队列 if(_step(x,y)<minstep){ minstep=_step(x,y) ; point t ,th ; t.x=x,t.y=y ; if(flag) QueuePop(&Q,&th) ;//如果是第一次的话,就不用出队列了; QueueAppend(&Q,t) ; flag=1; } } } } return step-1; } int main() { cout<<"输入起始位置,以空格作为间距::"<<endl; while(scanf("%d%d",&m,&n)!=EOF){ //判断起始位置是否合法 if(m<0||m>7||n<0||n>7){ printf("起始位置不合法!\n\n"); }else { printf("\n"); memset(map,0,sizeof(map));//将8*8的棋盘全部置为0 point start; start.x=m,start.y=n; step=1; step=BFS(start); //按求出的行走路线,将数字1, 2, 3,…,64依次填入一个8×8的方阵,输出 for(int i=0;i<MAXN;i++){ for(int j=0;j<MAXN;j++){ printf("%-3d",map[i][j]); } printf("\n"); } printf("step=%d.\n",step); printf("\n"); } } return 0; }
相关文章推荐
- 探索 Python 代码对象
- HDU 2200 Eddy's AC难题(组合数学)
- 10.Spark Streaming源码分析:Receiver数据接收全过程详解
- 细数5款主流NoSQL数据库到底哪家强?
- 第12周项目1实现复数类的运算符重载3
- 百度 API 生成短网址自己测试的例子
- 第十三周项目—阅读程序,并运行结果(纯虚函数)
- 深入理解JavaScript系列+ 深入理解javascript之执行上下文
- 第十一周阅读项目(5)
- 猴子吃桃问题
- Random Forest 随机森林
- 基于FS4412嵌入式系统移植(8) linux内核调试之printk
- Java中判断对象是否相等的equals()方法使用教程
- css word-wrap和word-break强制换行
- 我们应该如何去了解JavaScript引擎的工作原理 系列
- HDU4355(三分)
- Chp15 网络编程
- NoSQL数据库概览及其与SQL语法的比较
- 小代码 代码整理
- ssh框架中的basedao