马踏棋盘回溯算法C++源代码

合集下载

一个用C++编写的马踏棋盘递归算法源程序

一个用C++编写的马踏棋盘递归算法源程序
FootPrint(curposnext,curstep+1);/*当前位置留下脚印*/
HorseChess(curstep+1,curposnext);
}
}
FreePrint(curpos);
}
void main(){
int i,j;
}
}
void HorseChess(int curstep,PosType curpos){
int j;
PosType curposnext;
if(curstep==1)FootPrint(curpos,1);
if(curstep==64){
sum++;
printf("sum=%4d",sum);
PrintBoard();
printf("\n");
}
else for(j=0;j<8;++j){
curposnext = NextPos(curpos,j);/*下一个位置*/
if(Pass(curposnext)){
PosType start;
InitBoard();
printf("\nPlease input i and j:");
scanf("%d%d",&i,&j);
if(!(i<0 || j<0 || i>=M || j>=N)){
start.r = i;
start.c = j;
int i,j;
i = curpos.r;
j = curpos.c;

数据结构马踏棋盘

数据结构马踏棋盘

实验二:栈和队列及其应用题目:马踏棋盘班级:姓名:学号:一、问题描述设计一个国际象棋的马踏遍棋盘的演示程序。

二、基本要求将马随机放在国际象棋的8*8的棋盘Board[8][8]的某个方格中,马按走棋规则进行移动。

要求每个方格只进入一次,走遍棋盘上全部64个方格。

编制非递归程序,求出马的行走路线,并按求出的行走路线,将数字1,2,……,64依次填入一个8*8的方阵,输出之。

三、概要设计1.定义头文件和预定义#include<stdio.h>#define MAXSIZE 100#define N 82.起始坐标函数:void InitLocation(int xi,int yi);3.探寻路径函数:int TryPath(int i,int j);4.输出路径函数:void Display();5.主程序:void main();四、详细设计1.函数声明void InitLocation(int xi,int yi); //马儿在棋盘上的起始位置坐标int TryPath(int i,int j); //马儿每个方向进行尝试,直到试完整个棋盘void Display(); //输出马儿行走的路径2. 起始坐标函数模块void InitLocation(int xi,int yi){int x,y; //定义棋盘的横纵坐标变量top++; //栈指针指向第一个栈首stack[top].i=xi; //将起始位置的横坐标进栈stack[top].j=yi; //将起始位置的纵坐标进栈stack[top].director=-1; //将起始位置的尝试方向赋初值board[xi][yi]=top+1; //标记棋盘x=stack[top].i; //将起始位置的横坐标赋给棋盘的横坐标y=stack[top].j; //将起始位置的纵坐标赋给棋盘的纵坐标if(TryPath(x,y)) //调用马儿探寻函数,如果马儿探寻整个棋盘返回1否则返回0Display(); //输出马儿的行走路径elseprintf("无解");}3. 探寻路径函数模块int TryPath(int i,int j){int find,director,number,min; //定义几个临时变量int i1,j1,h,k,s; //定义几个临时变量int a[8],b1[8],b2[8],d[8]; //定义几个临时数组while(top>-1) //栈不空时循环{for(h=0;h<8;h++) //用数组a[8]记录当前位置的下一个位置的可行路径的条数{number=0;i=stack[top].i+Htry1[h];j=stack[top].j+Htry2[h];b1[h]=i;b2[h]=j;if(board[i][j]==0&&i>=0&&i<8&&j>=0&&j<8) //如果找到下一位置{for(k=0;k<8;k++){i1=b1[h]+Htry1[k];j1=b2[h]+Htry2[k];if(board[i1][j1]==0&&i1>=0&&i1<8&&j1>=0&&j1<8)//如果找到下一位置number++; //记录条数}a[h]=number; //将条数存入数组a[8]中}}for(h=0;h<8;h++) //根据可行路径条数小到大按下表排序放入数组d[8]中{min=9;for(k=0;k<8;k++)if(min>a[k]){min=a[k];d[h]=k; //将下表存入数组d[8]中s=k;}a[s]=9;}director=stack[top].director;if(top>=63) //如果走完整个棋盘返回1return (1);find=0; //表示没有找到下一个位置for(h=director+1;h<8;h++) //向八个方向进行探寻{i=stack[top].i+Htry1[d[h]];j=stack[top].j+Htry2[d[h]];if(board[i][j]==0&&i>=0&&i<8&&j>=0&&j<8) //如果找到下一位置{find=1; //表示找到下一个位置break;}}if(find==1) //如果找到下一个位置进栈{stack[top].director=director; //存储栈结点的方向top++; //栈指针前移进栈stack[top].i=i;stack[top].j=j;stack[top].director=-1; //重新初始化下一栈结点的尝试方向board[i][j]=top+1; //标记棋盘}else //否则退栈{board[stack[top].i][stack[top].j]=0; //清除棋盘的标记top--; //栈指针前移退栈}}return (0);}4. 输出路径函数模块void Display(){int i,j;for(i=0;i<N;i++){for(j=0;j<N;j++)printf("\t%d ",board[i][j]); //输出马儿在棋盘上走过的路径printf("\n\n");}printf("\n");}五、测试数据及测试结果测试数据:x=2,y=3测试结果:六、实验环境C-Free七、源程序代码#include<stdio.h>#define MAXSIZE 100#define N 8int board[8][8]; //定义棋盘int Htry1[8]={1,-1,-2,2,2,1,-1,-2};/*存储马各个出口位置相对当前位置行下标的增量数组*/int Htry2[8]={2,-2,1,1,-1,-2,2,-1};/*存储马各个出口位置相对当前位置列下标的增量数组*/struct Stack{ //定义栈类型int i; //行坐标int j; //列坐标int director; //存储方向}stack[MAXSIZE]; //定义一个栈数组int top=-1; //栈指针void InitLocation(int xi,int yi); //马儿在棋盘上的起始位置坐标int TryPath(int i,int j); //马儿每个方向进行尝试,直到试完整个棋盘void Display(); //输出马儿行走的路径void InitLocation(int xi,int yi){int x,y; //定义棋盘的横纵坐标变量top++; //栈指针指向第一个栈首stack[top].i=xi; //将起始位置的横坐标进栈stack[top].j=yi; //将起始位置的纵坐标进栈stack[top].director=-1; //将起始位置的尝试方向赋初值board[xi][yi]=top+1; //标记棋盘x=stack[top].i; //将起始位置的横坐标赋给棋盘的横坐标y=stack[top].j; //将起始位置的纵坐标赋给棋盘的纵坐标if(TryPath(x,y)) //调用马儿探寻函数,如果马儿探寻整个棋盘返回1否则返回0Display(); //输出马儿的行走路径elseprintf("无解");}int TryPath(int i,int j){int find,director,number,min; //定义几个临时变量int i1,j1,h,k,s; //定义几个临时变量int a[8],b1[8],b2[8],d[8]; //定义几个临时数组while(top>-1) //栈不空时循环{for(h=0;h<8;h++) //用数组a[8]记录当前位置的下一个位置的可行路径的条数{number=0;i=stack[top].i+Htry1[h];j=stack[top].j+Htry2[h];b1[h]=i;b2[h]=j;if(board[i][j]==0&&i>=0&&i<8&&j>=0&&j<8) //如果找到下一位置{for(k=0;k<8;k++){i1=b1[h]+Htry1[k];j1=b2[h]+Htry2[k];if(board[i1][j1]==0&&i1>=0&&i1<8&&j1>=0&&j1<8)//如果找到下一位置number++; //记录条数}a[h]=number; //将条数存入数组a[8]中}}for(h=0;h<8;h++) //根据可行路径条数小到大按下表排序放入数组d[8]中{min=9;for(k=0;k<8;k++)if(min>a[k]){min=a[k];d[h]=k; //将下表存入数组d[8]中s=k;}a[s]=9;}director=stack[top].director;if(top>=63) //如果走完整个棋盘返回1return (1);find=0; //表示没有找到下一个位置for(h=director+1;h<8;h++) //向八个方向进行探寻{i=stack[top].i+Htry1[d[h]];j=stack[top].j+Htry2[d[h]];if(board[i][j]==0&&i>=0&&i<8&&j>=0&&j<8) //如果找到下一位置{find=1; //表示找到下一个位置break;}}if(find==1) //如果找到下一个位置进栈{stack[top].director=director; //存储栈结点的方向top++; //栈指针前移进栈stack[top].i=i;stack[top].j=j;stack[top].director=-1; //重新初始化下一栈结点的尝试方向board[i][j]=top+1; //标记棋盘}else //否则退栈{board[stack[top].i][stack[top].j]=0; //清除棋盘的标记top--; //栈指针前移退栈}}return (0);}void Display(){int i,j;for(i=0;i<N;i++){for(j=0;j<N;j++)printf("\t%d ",board[i][j]); //输出马儿在棋盘上走过的路径printf("\n\n");}printf("\n");}int main(){int i,j;int x,y;for(i=0;i<N;i++) //初始化棋盘for(j=0;j<N;j++)board[i][j]=0;for(;;){printf("Please input importpoint(1<=x<=8 and 1<=y<=8)\n");printf("Input x = ");scanf("%d",&x); //输入起始位置的横坐标printf("Input y = ");scanf("%d",&y); //输入起始位置的纵坐标if(x>=1&&x<=8&&y>=1&&y<=8)break;printf("Your input is worng!!!\n");}printf("begin with %d board:\n\n", 8*(x-1)+y);InitLocation(x-1,y-1); //调用起始坐标函数}。

骑士路线(国际象棋的马不重复的走完棋盘代码)(回溯)

骑士路线(国际象棋的马不重复的走完棋盘代码)(回溯)
ptr1[num].y = row + 2;
num++;
}//finished
return ptr1;
}
inline bool Check(const int & a, const int & b)
{
if (0 <= a && a < MAX && 0 <= b && b < MAX) return true;
// algorithm work.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#incБайду номын сангаасude <omp.h>
#define MAX 8 //MAX*MAX的矩阵,可修改
using namespace std;
ptr1[num].x = col+1;
ptr1[num].y = row-2;
num++;
}
if (Check(row - 2, col - 1)) {
ptr1[num].x = col-1;
ptr1[num].y = row-2;
num++;
}
if (Check(row - 1, col - 2)) {
else return false;
}
Move::Move()
{
x = 0; y = 0;
}
Move::Move(int a, int b)

马踏棋盘算法——递归实现(回溯法、深度优先遍历)

马踏棋盘算法——递归实现(回溯法、深度优先遍历)

马踏棋盘算法——递归实现(回溯法、深度优先遍历)背景:在学习数据结构时,关于图的遍历的⼀个经典问题,这⾥采⽤递归的⽅式实现该算法,其中包含回溯法和图的深度优先遍历的思想,在参考各种递归实现该算法的基础上,完成了⼀版带有⾃⼰理解的详细注释版代码开发环境:Code::Blocks编译器:GCC语⾔:C代码:(详细注释)/* 递归+回溯+图深度优先遍历 */#include <stdio.h>#include <time.h>#define X 8#define Y 8int chess[X][Y];/* 判断⼋个⽅向是否有可以⾛的点 */int nextxy_1(int *x,int *y,int count){/* count表⽰8个⽅向 */switch(count){case 0:/* 该⽅向没有超出边界且之前未⾛过 */if(*x+2<X && *y+1<Y && chess[*x+2][*y+1]==0){/* 该⽅向可⾛则修改当前位置 */*x+=2;*y+=1;/* 有⽅向可⾛则返回1 */return 1;}break;case 1:if(*x+2<X && *y-1>=0 && chess[*x+2][*y-1]==0){*x+=2;*y-=1;return 1;}break;case 2:if(*x+1<X && *y-2>=0 && chess[*x+1][*y-2]==0){*x+=1;*y-=2;return 1;}break;case 3:if(*x-1>=0 && *y-2>=0 && chess[*x-1][*y-2]==0){*x-=1;*y-=2;return 1;}break;case 4:if(*x-2>=0 && *y-1>=0 && chess[*x-2][*y-1]==0){*x-=2;*y-=1;return 1;}break;case 5:if(*x-2>=0 && *y+1<Y && chess[*x-2][*y+1]==0){*x-=2;*y+=1;}break;case 6:if(*x-1>=0 && *y+2<Y && chess[*x-1][*y+2]==0){*x-=1;*y+=2;return 1;}break;case 7:if(*x+1<X && *y+2<Y && chess[*x+1][*y+2]==0){*x+=1;*y+=2;return 1;}break;default:/* ⽆⽅向可⾛ */break;}/* 8个⽅向均不可⾛则换回0 */return 0;}/* 判断⼋个⽅向是否有可以⾛的点优于nextxy_1 *//* 这⾥参考⽹络上的⼀个优化:https:///ppalive_/article/details/47728475 */ /* 采⽤nexty_1或nextxy_2函数在整理算法理解上并不重要 *//* 区别在于寻找下⼀个⽅向的顺序 */int nextxy_2(int *x,int *y,int count){switch(count){case 0:if(*x+2<X && *y-1>=0 && chess[*x+2][*y-1]==0){*x+=2;*y-=1;return 1;}break;case 1:if(*x+2<X && *y+1<Y && chess[*x+2][*y+1]==0){*x+=2;*y+=1;return 1;}break;case 2:if(*x+1<X && *y-2>=0 && chess[*x+1][*y-2]==0){*x+=1;*y-=2;return 1;}break;case 3:if(*x+1<X && *y+2<Y && chess[*x+1][*y+2]==0){*x+=1;*y+=2;return 1;}break;case 4:if(*x-2>=0 && *y-1>=0 && chess[*x-2][*y-1]==0){*x-=2;*y-=1;return 1;}break;if(*x-2>=0 && *y+1<Y && chess[*x-2][*y+1]==0){*x-=2;*y+=1;return 1;}break;case 6:if(*x-1>=0 && *y-2>=0 && chess[*x-1][*y-2]==0){*x-=1;*y-=2;return 1;}break;case 7:if(*x-1>=0 && *y+2<Y && chess[*x-1][*y+2]==0){*x-=1;*y+=2;return 1;}break;default:break;}return 0;}/* 输出计算出来的⾛法 */void print(){int i,j;for(i=0;i<X;++i){for(j=0;j<Y;++j){/* tab分割 */printf("%2d\t",chess[i][j]);}/* enter分割 */printf("\n");}printf("\n");}/* 遍历棋盘 */int TravelChessBoard(int x,int y,int tag){int x1 = x;int y1 = y;int flag = 0;int count = 0;/* tag 标记⾜迹 */chess[x][y] = tag;/* 棋盘遍历完成 */if(tag == X*Y){/* 打印遍历结果 */print();return 1;}/* ⾛第⼀个⽅向 */flag = nextxy_2(&x1,&y1,count);/* ⾛不通则切换⽅向(8个⽅向都尝试) */while(flag == 0 && count <= 7){++count;flag=nextxy_2(&x1,&y1,count);}/* 如果所有⽅向都⾛不通则跳到if(flag==0) 清除当前位置的⾜迹 */ /* 如果找到能⾛的⽅向就进⾏下⼀次递归(⾛下⼀步) */while(flag){/* 完成遍历(TravelChessBoard函数返回1) *//* 这⾥如果每⼀次递归都能在8个⽅向种找到可以⾛地⽅向,则递归会⼀直深⼊(深度优先) *//* 递归⼀直深⼊则相当于函数TravelChessBoard每次都只运⾏到这⾥ */if(TravelChessBoard(x1,y1,tag+1))return 1;/* ⼀直到递归到某个深度之后,8个⽅向都没有可⾏路径,则TravelChessBoard函数返回⼀次0 *//* 这种情况下 TravelChessBoard函数将运⾏到这⾥ *//* 也就是说之前⾛的路径是⽆法完成遍历的所以需要退回上⼀步选择其他路径尝试(切换下⼀个⽅向) *//* 这⾥相当于是退回到了上⼀层的递归以下操作读取上⼀层递归中的坐标将上⼀层递归中的⽅向+1(切换⽅向) */ /* 当前路径⽆法完成遍历(TravelChessBoard函数返回0) */x1=x;y1=y;++count;/* 尝试下⼀个⽅向 */flag=nextxy_2(&x1,&y1,count);/* ⽅向尝试失败则切换下⼀个⽅向进项尝试 *//* 这⾥count的条件为<7的原因是:上⼀次⾛的⽅向已经被证明失败不在选择与上⼀次同样的⽅向 */while(flag==0 && count<7){++count;flag=nextxy_2(&x1,&y1,count);}/* 如果所有⽅向再次尝试失败则再次运⾏到if(flag==0)语句,即将再次退出⼀层递归,重新选择该层的路径 */}/* 当前位置向各个⽅向都⾛不通 */if(flag==0){/* 则情况当前位置的⾜迹 */chess[x][y]=0;}return 0;}int main(){int i,j;clock_t start,finish;/* 获取算法开始时的系统tick */start=clock();/* 初始化棋盘 */for(i=0;i<X;++i){for(j=0;j<Y;++j)chess[i][j]=0;}/* 起始点(2,0)遍历棋盘 */if(!TravelChessBoard(2,0,1)){/* 若遍历失败 */printf("failed!\n");}/* 获取算法结束时的系统tick */finish=clock();/* 计算算法耗时 */printf("\n time consume:%f second\n\n",(double)(finish-start)/CLOCKS_PER_SEC);return 0;}——cloud over sky——2020/3/11。

C++贪心算法实现马踏棋盘

C++贪心算法实现马踏棋盘

C++贪⼼算法实现马踏棋盘本⽂实例为⼤家分享了C++贪⼼算法实现马踏棋盘的具体代码,供⼤家参考,具体内容如下算法实现流程:步骤1:初始化马的位置(结构体horse {x, y})步骤2:确定马从当前点出发,可跳跃的附近8个点,以结构体Jump数组给出,但需判断当前给出的附近8个点是否曾经访问过,或者是否这8个点超出棋盘尺⼨。

步骤3:跟据步骤2确定跳跃的点,分别计算可跳跃点的下下⼀步,可跳跃点的个数。

并选出下下步可跳跃点数最少的点作为马下⼀步跳跃的点。

(举例说明:马当前所在点坐标(4,4),下⼀步可跳跃点有(5,2),(6,3),且(5,2)下⼀步可跳跃点有3个,(6,3)下⼀步可跳跃点2个;3 > 2这个时候,选择下下⼀跳⼩的点进⾏跳跃,则马下⼀跳为(6,3))流程图:#pragma once#include <iostream>#include <math.h>using namespace std;#define SAFE_DELETE(x) if (x != NULL) {delete(x); x = NULL;}#define SAFE_DELETE_ARR(x) if (x != NULL) {delete[](x); x = NULL;}#define PRING_ARR(title, arr, n) {cout << title << " "; for (int i=0; i<n; i++) {cout << arr[i] << " ";} cout << endl;}#define INF 9999999typedef struct{int x;int y;}Location;typedef struct{int delx;int dely;}Jump;class HorseRun{private:int** altas;int N; //棋盘的宽Location horse; //马当前的位置public:HorseRun(){N = 8;altas = new int* [N]();for (int j = 0; j < N; j++){altas[j] = new int[N]();memset(altas[j], 0, sizeof(int) * N);}//随机⽣成马的初始位置horse = { rand() % N, rand() % N };altas[horse.x][horse.y] = 1;cout << "马初始位置:" << "(" << horse.x << "," << horse.y << ")" << endl;Visit();}~HorseRun(){for (int i = 0; i < N; i++)SAFE_DELETE_ARR(altas[i]);SAFE_DELETE_ARR(altas);}inline void Visit(){Jump jump[8] = { {1,-2}, {2, -1}, {2, 1}, {1, 2}, {-1, 2}, {-2, 1}, {-2, -1}, {-1, -2} };int max_visit = 63;int forward_x, forward_y, forward_xx, forward_yy, w_cnt, min_cnt, tmp_run_x, tmp_run_y;while (max_visit-- > 0){min_cnt = INF;//棋⼦可跳⼋个⽅位for (int i = 0; i < 8; i++){forward_x = horse.x + jump[i].delx;forward_y = horse.y + jump[i].dely;//判断这两个坐标是否有效if (forward_x < 0 || forward_x >= N || forward_y < 0 || forward_y >= N || altas[forward_x][forward_y] == 1)continue;w_cnt = 0;for (int j = 0; j < 8; j++){forward_xx = forward_x + jump[j].delx;forward_yy = forward_y + jump[j].dely;if (forward_xx < 0 || forward_xx >= N || forward_yy < 0 || forward_yy >= N || altas[forward_xx][forward_yy] == 1)continue;w_cnt++;}if (min_cnt > w_cnt){min_cnt = w_cnt;tmp_run_x = forward_x;tmp_run_y = forward_y;}}//棋⼦移动判断if (min_cnt == INF){cout << "没有找到可以移动的地⽅" << endl;break;}else{horse.x = tmp_run_x;horse.y = tmp_run_y;altas[tmp_run_x][tmp_run_y] = 1;cout <<"第"<< 63 - max_visit << "步," << "棋⼦当前移动到:" << "(" << tmp_run_x << ", " << tmp_run_y << ")" << endl; }}}};#define _CRT_SECURE_NO_WARNINGS true#include "HorseRun.h"int main(){HorseRun app;return 0;}运⾏结果输出1-63步马⾏驶的具体路径信息:中间还有很多输出省略。

利用顺序栈或循环队列的存储来实现马踏棋盘的算法

利用顺序栈或循环队列的存储来实现马踏棋盘的算法

河南工业大学实验报告课程数据结构实验名称利用顺序栈或循环队列的存储来实现马踏棋盘的算法学院信息科学与工程学院专业班级姓名学号实验报告日期 2009 年 4 月 1 日教师审批签字实验报告一实验题目:马踏棋盘二实验要求:将马放在国际象棋的8*8棋盘Board[8][8]的某个方格中,马按走棋的规则进行移动。

要求每个方格只能进入一次。

走遍棋盘上的全部的64个方格。

输入:任意一个起始位置.输出:无重复踏遍棋盘的结果,以数字1-64表示行走路线.数据结构要求:采用顺序栈或者链栈实现三实验目的:1熟悉栈的定义和栈的基本操作2 熟悉每一种栈操作的一般函数实现和成员函数实现。

3在实际问题背景下灵活运用它们,并巩固这两种结构的构造方法四程序设计如下:#include "stdio.h"#define M 70#define FALSE 0#define TRUE 1typedef struct node //结点的类型{int vec,x,y;struct node *link;}listnode;#define MAXSIZE 70typedef struct{int stack[MAXSIZE];int top;}seqstack;seqstack *s; //顺序栈指针listnode ag[M];int flag[M];void setnull(seqstack *s){s->top=-1;}int push(seqstack *s,int x){if(s->top>=MAXSIZE-1){printf("stack overflow!\n");return FALSE;}else{s->stack[++s->top]=x;/*栈顶指针上移,数据元素入栈*/ return TRUE;}}int pop(seqstack *s)/*出当前栈S的栈顶元素*/{ int p;if(s->top<0){printf("stack empty!\n");/*栈空,返回空值 */ return NULL;}else{s->top--;return(s->stack[s->top+1]);}/*由于return语句的特点,必须先使top减1,然后再执行return语句。

03-8.3 贪心法解马踏棋盘

03-8.3 贪心法解马踏棋盘

程序设计与问题求解——马踏棋盘(贪心法)主讲教师:仇国巍国际象棋棋盘是8*8的方格,现将“马”放在任意指定的方格中,按照走棋规则移动该棋子。

要求每个方格只能进入一次,最终走遍棋盘64个方格xy棋盘可用一个矩阵表示,当“马”位于棋盘上某一位置时,它就有一个唯一的坐标。

根据规则,如果当前坐标是(x,y),那么它的下一跳可能有8个位置,分别是(x+2,y-1)、(x+2,y+1)、(x+1,y+2)、(x-1,y+2)、(x-2,y+1)、(x-2,y-1)、(x-1,y-2)、(x+1,y-2)。

当然坐标不能越界马最初的位置标为1,它的下一跳的位置标为2,再下一跳的位置标为3,依次类推,如果马走完棋盘,那么最后在棋盘上标的位置是64要求编程解决马踏棋盘问题,最后输出一个8*8的矩阵,并用数字1-64来标注“马”的移动基本解法:深度优先搜索从某位置出发,先试探下一个可能位置;进入一个新位置后就从该位置进一步试探下一位置,若遇到不可行位置则回退一步,然后再试探其他可能位置bool Dfs(int chess[][8], int x, int y, int j){}马踏棋盘——深度优先搜索求解可以用8*8数组chess[][] 存储棋子周游状态,未走过位置赋0,走过的位置依次为1、2、3、……。

设(x,y)为当前位置,j 为当前走到第几步// 深度优先搜索求解核心代码chess[x][y] = j; //将新的一步标注到矩阵中if (j == 64) return true; //成功!依次回退结束程序计算下一可能位置(nextX, nextY);//不考虑是否可行while ( (nextX, nextY)位置是否可行) {if (Dfs(chess, nextX, nextY, j+1)) //递归调用,将进入新位置return true;计算下一可能位置(nextX, nextY); }chess[x][y] = 0; //这一步不可走,回退return false;马踏棋盘——深度优先搜索………………再下一步…a1a4…b1b3…c1c5…下一步L1L2L8位置(x, y)至此已不满足约束条件深度优先搜索求解,相当于在类似下面的树中查询………………再下一步…a1a4…b1b3…c1c5…下一步L1L2L8位置(x, y)◆从(x,y)开始,深度优先搜索会依次查询L1、L2、……、L8一共8个可能位置◆如何加入贪心策略????先试探哪一个位置,更可能得到答案呢?◆事实上,先选择L1~L8中哪个位置试探,可利用L1~L8位置的子结点个数确定贪心策略:在选择下一跳的位置时,总是先选择出口少的那个位置………………再下一次决策…a1a4…b1b3…c1c5…下次决策位置1位置2位置8位置(x, y)如果优先选择出口多的子结点,那么出口少的子结点就会越来越多,很可能出现走不通的‘死’结点。

马踏棋盘C语言

马踏棋盘C语言

#include<malloc.h>#include<limits.h>#include<stdio.h>#include<math.h>#include<process.h>#include<conio.h>#include<dos.h>#define CLS system("cls")#define TRUE 1#define FALSE 0#define OK 1#define ERROR 1#define STACK_INIT_SIZE 10 /* 存储空间初始分配量*/#define STACKINCREMENT 2 /* 存储空间分配增量*/#define N 8 /*定义棋盘大小*/typedef int Status;typedef struct chess{int x;int y;int z;}SElemType;int map[N][N][8]; /*按各点权值递升存放待走方向,每点8个*/int weight[N][N]; /*各点的权值*/int board[N][N]; /*棋盘,未走过时值为0,走过后值为1*/static SElemType HTry[8]= /* 8个候选方向的偏移值*/{{-2, 1, 0},{ -1, 2, 0},{ 1, 2, 0},{ 2, 1, 0},{ 2, -1, 0}, {1, -2, 0}, {-1, -2, 0}, {-2, -1, 0} };void setweight();/*求各点权值*/void setmap(); /*各点的8个方向按权值递增排列*/void Path(int x, int y); /*主算法函数,踏遍棋盘*//*栈的顺序存储表示*/typedef struct SqStack{SElemType *base; /* 在栈构造之前和销毁之后,base的值为NULL */SElemType *top; /* 栈顶指针*/int stacksize; /* 当前已分配的存储空间,以元素为单位*/}SqStack; /* 顺序栈*/Status InitStack(SqStack *S) /* 构造一个空栈S */{S->base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));if(!S->base)exit(OVERFLOW); /* 存储分配失败*/S->top=S->base;S->stacksize=STACK_INIT_SIZE;return OK;}Status StackEmpty(SqStack S){ /* 若栈S为空栈,则返回TRUE,否则返回FALSE */if(S.top==S.base)return TRUE;elsereturn FALSE;}Status GetTop(SqStack S,SElemType *e){ /* 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR */ if(S.top>S.base){*e=*(S.top-1);return OK;}elsereturn ERROR;}Status SetTop(SqStack S,SElemType *e){if(S.top>S.base){(e->z)++;*(S.top-1)=*e;return OK;}elsereturn ERROR;}Status Push(SqStack *S,SElemType e){ /* 插入元素e为新的栈顶元素*/if(S->top-S->base==S->stacksize) /* 栈满,追加存储空间*/{S->base=(SElemType*)realloc(S->base,(S->stacksize+STACKINCREMENT)*sizeof(SElemType));if(!S->base)exit(OVERFLOW); /* 存储分配失败*/S->top=S->base+S->stacksize;S->stacksize+=STACKINCREMENT;}*(S->top)++=e;return OK;}Status Pop(SqStack *S,SElemType *e){ /* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */ if((*S).top==(*S).base)return ERROR;*e=*--(*S).top;return OK;}void main()/*主函数*/{int x,y;int i,j,k=0;for(i=0;i<N;i++)for(j=0;j<N;j++)board[i][j]=0;setweight();setmap();while(1){printf("输入马的行坐标X (from 0 to 7):");scanf("%d",&x);printf("输入马的列坐标Y (from 0 to 7):");scanf("\n%d",&y);if(x<0||x>7||y<0||y>7){printf("输入错误!\n\n");flushall();}elsebreak;}Path(x,y);}/*end main()*//*求各点权值:可走的方向数.该值越小,则被上一点选中的可能性越大*/void setweight(){int i,j,k,x1,y1;for(i=0;i<N;i++)/*for 1*/{for(j=0;j<N;j++)/*for 2*/{weight[i][j]=0;for(k=0;k<N;k++)/*for 2*/{x1=i+HTry[k].x;y1=j+HTry[k].y;if(x1>=0&&x1<N&&y1>=0&&y1<N){weight[i][j]++;/*即在8个方向中,(i,j)点有几个方向可以移动*/ }}}} /*end of for 1 */}/*end setweight()*//*检查(i,j)是否在棋盘内*/int check(int i,int j){if(i<0||i>=8||j<0||j>=8)return 0;return 1;}/*将各点的8个方向按该方向下的目标点的权值递增排列*/void setmap(){int i,j,k,m,d1,d2,x1,x2,y1,y2,l1,l2;for(i=0;i<N;i++)/*for 1*/{for(j=0;j<N;j++)/*for 2*/{for(k=0;k<8;k++)map[i][j][k]=k;/*默认8个方向顺时针赋值*/for(k=0;k<8;k++) /*选择排序for 3 与for 4 两个循环对方向索引按点的权值升序排列,不能到达的方向排在最后*/{for(m=k+1;m<8;m++) /*for 4*/{d1=map[i][j][k];x1=i+HTry[d1].x;y1=j+HTry[d1].y;d2=map[i][j][m];x2=i+HTry[d2].x;y2=j+HTry[d2].y;l1=check(x1,y1);l2=check(x2,y2);if((l1==0&&l2)||(l1&&l2&&(weight[x1][y1]>weight[x2][y2]))){map[i][j][k]=d2;map[i][j][m]=d1; /*交换两个方向值,按权值递增排列,不可到达的目标点(超出棋盘)的方向放在最后面*/}/*end if*/}/*end for 4*/}/*end for 3*/}/*end for 2*/}/*end for 1*/}/*end setmap()*//*输出函数*/void output(SqStack &a){ SqStack b;int c[8][8]={0},j,k=N*N,l=1,x,y;InitStack (&b);SElemType e;while(!StackEmpty(a)){Pop(&a,&e);c[e.x][e.y]=k;k--;Push(&b,e);}GetTop(b,&e);x=e.x;y=e.y;printf("起始坐标:(%d,%d)\n",x,y);while(!StackEmpty(b)){ Pop(&b,&e);printf("(%d,%d)",e.x,e.y);Push(&a,e);}printf("棋盘表示: 0 1 2 3 4 5 6 7\n"); printf(" ┌─┬─┬─┬─┬─┬─┬─┬─┐\n");printf(" 0");for(j=0;j<=7;j++){if(c[0][j]<10) printf("│ %d",c[0][j]);elseprintf("│%d",c[0][j]);}printf("│\n");printf(" ");printf("├─┼─┼─┼─┼─┼─┼─┼─┤\n");printf(" 1");for(j=0;j<=7;j++){ if(c[1][j]<10) printf("│ %d",c[1][j]);elseprintf("│%d",c[1][j]);}printf("│\n");printf(" ");printf("├─┼─┼─┼─┼─┼─┼─┼─┤\n");printf(" 2");for(j=0;j<=7;j++){ if(c[2][j]<10) printf("│ %d",c[2][j]);elseprintf("│%d",c[2][j]);}printf("│\n");printf(" ");printf("├─┼─┼─┼─┼─┼─┼─┼─┤\n");printf(" 3");for(j=0;j<=7;j++){ if(c[3][j]<10) printf("│ %d",c[3][j]);elseprintf("│%d",c[3][j]);}printf("│\n");printf(" ");printf("├─┼─┼─┼─┼─┼─┼─┼─┤\n");printf(" 4");for(j=0;j<=7;j++){ if(c[4][j]<10) printf("│ %d",c[4][j]);elseprintf("│%d",c[4][j]);}printf("│\n");printf(" ");printf("├─┼─┼─┼─┼─┼─┼─┼─┤\n");printf(" 5");for(j=0;j<=7;j++){ if(c[5][j]<10) printf("│ %d",c[5][j]);elseprintf("│%d",c[5][j]);}printf("│\n");printf(" ");printf("├─┼─┼─┼─┼─┼─┼─┼─┤\n");printf(" 6");for(j=0;j<=7;j++){if(c[6][j]<10) printf("│ %d",c[6][j]);elseprintf("│%d",c[6][j]);}printf("│\n");printf(" ");printf("├─┼─┼─┼─┼─┼─┼─┼─┤\n");printf(" 7");for(j=0;j<=7;j++){if(c[7][j]<10) printf("│ %d",c[7][j]);elseprintf("│%d",c[7][j]);}printf("│\n");printf(" ");printf("└─┴─┴─┴─┴─┴─┴─┴─┘\n");}/*踏遍棋盘算法*/void Path(int xx, int yy){int c[N*N]={0},h[N*N]={0};SqStack a;SElemType ptemp;SElemType pop_temp,get_temp;SElemType p,dest_p; /*当前点和目标点*/int step=0,x,y,s,k=1,l=1,d =0;char ch;p.x = xx; p.y = yy;p.z = 0;/*初始化出发点*/board[xx][yy]=1;InitStack(&a);Push(&a,p); /*起始点的坐标和首选方向入栈*/while(1){if (step==(N*N-1)){output(a);printf("退出/返回/下一条路径?q/b/n\n");printf("第%d条路径",k);ch=getch();if(ch=='b') {CLS;main();}elseif(ch=='q') exit(1);else /*寻找下一条路径*/{k++;/*路径数加1*/Pop(&a,&pop_temp); /*退栈*/GetTop(a,&get_temp); /*取当前栈顶元素*/SetTop(a,&ptemp); /*更改方向*/step--;continue;}}if(StackEmpty(a)) break;GetTop(a,&p);x=p.x; y=p.y; d=p.z;if(d>=8)/*该点所有方向已走完,退栈*/{board[x][y]=0; /*抹去痕迹*/step--; /*步数减一*/Pop(&a,&pop_temp); /*退栈*/GetTop(a,&get_temp); /*取当前栈顶元素*/SetTop(a,&get_temp); /*更改方向*/} /*end if (d>=8)*/if(d<8)/*方向未走完*/{s=map[x][y][d];/*map[x][y][0]未必是(x,y)点的HTry[0]方向,而是到该点可到的权值最小的点的方向即HTry[map[x][y][0]*/ dest_p.x=x+HTry[s].x;dest_p.y=y+HTry[s].y;if(check(dest_p.x,dest_p.y)&&board[dest_p.x][dest_p.y]==0)/*目标点在棋盘内且未被走过,则将目标点入栈同时标记当前点为已走过*/{h[step]=step;board[x][y]=1;step++;/*步数加一*/dest_p.z=0;Push(&a,dest_p);/*存入目标点,方向栈初始*/}else/*目标点已被走过或目标点不在棋盘内,换方向*/SetTop(a,&p);/*切换方向*/} /*enf if(d<8)*/} /*end while(1)*/}。

递归遍历算法实现“马踏棋盘”

递归遍历算法实现“马踏棋盘”

题目:国际象棋的棋盘是8*8共64个位置,把“马”放在棋盘上任意位置都能走遍所有的位置,并且“马”只能走“斜日”。

请打印出来马走的路径。

实验程序:#include<iostream>#include<vector>#include<set>#include<map>#include<stack>#include<string>#include<math.h>#include<time.h>using namespace std;struct coord{int x;int y;};int chessboad[8][8]={0},curstep,num=0;coordmovet[8]={{-2,1},{-2,-1},{-1,2},{-1,-2},{1,2},{1,-2},{2,-1},{2,1}}; void display(){for(int i=0;i<8;i++){for(int j=0;j<8;j++)cout<<chessboad[i][j]<<" ";cout<<endl;}}void trave12(coord curpos){coord next;cout<<num++<<endl;if(curpos.x <0 || curpos.y<0 ||curpos.x>7 || curpos.y>7) return;if(chessboad[curpos.x][curpos.y]>0)return;chessboad[curpos.x][curpos.y]=curstep;curstep++;if(curstep>64)display();else{for(int i=0;i<8;i++){next.x=curpos.x+movet[i].x;next.y=curpos.y+movet[i].y;if(next.x<0 || next.x>7 || next.y<0 || next.y>7);elsetrave12(next);}/*next.x=curpos.x+1;next.y=curpos.y+2;if((next.x>=0 && next.x<=7) && (next.y>=0 && next.y<=7)) trave12(next);next.x=curpos.x+1;next.y=curpos.y-2;if((next.x>=0 && next.x<=7) && (next.y>=0 && next.y<=7)) trave12(next);next.x=curpos.x+2;next.y=curpos.y+1;if((next.x>=0 && next.x<=7) && (next.y>=0 && next.y<=7)) trave12(next);next.x=curpos.x+2;next.y=curpos.y-1;if((next.x>=0 && next.x<=7) && (next.y>=0 && next.y<=7)) trave12(next);next.x=curpos.x-1;next.y=curpos.y+2;if((next.x>=0 && next.x<=7) && (next.y>=0 && next.y<=7)) trave12(next);next.x=curpos.x-1;next.y=curpos.y-2;if((next.x>=0 && next.x<=7) && (next.y>=0 && next.y<=7)) trave12(next);next.x=curpos.x-2;next.y=curpos.y+1;if((next.x>=0 && next.x<=7) && (next.y>=0 && next.y<=7)) trave12(next);next.x=curpos.x-2;next.y=curpos.y-1;if((next.x>=0 && next.x<=7) && (next.y>=0 && next.y<=7)) trave12(next);*/}chessboad[curpos.x][curpos.y]=0;curstep--;}主函数调用为:#include"stdafx.h"#include"example36_horse.h"int main(void){coord start;cout<<"please input the start coordinate:"<<endl;cin>>start.x>>start.y;if(start.x<1 || start.y<1 || start.x>8 ||start.y>8){cout<<"it's wrong!"<<endl;return 0;}start.x-=1;start.y-=1;curstep=1;trave12(start);system("pause");return 0 ;}。

C语言 棋盘游戏 源代码

C语言 棋盘游戏 源代码

# include <stdio.h> # include <stdlib.h>char matrix[3][3];/*定义游戏棋盘*/char check(void);void init_matrix(void);void get_player_move(void);void disp_matrix(void);int main(){char done;printf("This is the game of Tic Tac Toe.\n");done = ' ';init_matrix();do{disp_matrix();get_player_move();done = check();/*检测输赢*/if(done!= ' ')break;/*赢了*/done = check();/*检测输赢*/}while (done == ' ');if(done=='X') printf("You won!\n");else printf("Computer won!\n");disp_matrix();/*显示棋子的位置*/return 0;}/*初始化棋盘*/void init_matrix(void){int i,j;for(i=0;i<3;i++)for (j=0;j<3;j++)matrix[i][j] = ' ';}/*下棋者下*/void get_player_move(void){int x,y;printf("Enter coordinates for your X:");scanf("%d%d",&x,&y);x--;y--;if(matrix[x][y] !=' '){printf("Invalid move,try again.\n");get_player_move();}else matrix[x][y]='X';}/*计算机下*/for(i=0;i<3;i++){for (j=0;j<3;j++)if(matrix[i][j]== ' ')break;if(matrix[i][j]== ' ')break;}if(i*j==9){printf("draw\n");exit(0);}elsematrix[i][j]='O';}/*在屏幕上显示棋盘*/void disp_matrix(void){int t;for(t=0;t<3;t++){printf("%c|%c|%c",matrix[t][0],matrix[t][1],matrix[t][2]); if(t!=2)printf("\n-|-|-\n");}printf("\n");}/*看谁是赢着*/char check(void){int i;/*检查横行*/for(i=0;i<3;i++)if(matrix[i][0]==matrix[i][1]&&matrix[i][0]==matrix[i][2])return matrix[i][0];/*检查竖行*/for(i=0;i<3;i++)if(matrix[0][i]==matrix[1][i]&&matrix[0][i]==matrix[2][i])return matrix[0][i];/*检查对角线*/if(matrix[0][0]==matrix[1][1]&&matrix[1][1]==matrix[2][2]) return matrix[0][0];if(matrix[0][2]==matrix[1][1]&&matrix[1][1]==matrix[2][0]) return matrix[0][2];return ' ';}。

马的遍历问题(C++实现)

马的遍历问题(C++实现)

课程设计报告课程名称:题目:院系:专业:班级:学号:姓名:时间:目录一、需求分析 (2)1.问题描述: (2)2.基本要求 (2)二、概要设计 (2)1.数据结构 (2)2.程序模块 (3)三、详细设计 (4)四、调试分析 (9)五、用户手册 (9)六、测试结果 (10)七、参考文献 (13)棋盘求解题目:设计程序完成如下要求:在中国象棋棋盘上,对任一位置上放置的一个马,均能选择一个合适的路线,使得该棋子能按象棋的规则不重复地走过棋盘上的每一位置。

要求依次输出所走过的各位置的坐标。

一、需求分析1. 问题描述:中国象棋是10*9的棋盘,马的走法是“马走日”,这里忽略“蹩脚马”的情况,使马的遍历的问题简单化。

马在棋盘上遍历采用算法当中的深度优先算法和回溯法:回溯法是一种不断试探且及时纠正错误的搜索方法。

从入口出发,按某一个方向向前探索,若能走通并且未走过,即某处可以到达,则到达新点,否则试探下一方向;如果发生“阻塞”的情况,就是后面走不通的情况,则沿原路返回前一点,换下一个方向再继续试探,直到找到一条通路,或无路可走又返回到入口点。

在寻找下一步的时候,对周围的这几个点进行比较,从而分出优劣程度,即看它们周围可以走的点谁最少,然后就走那条可走路线最少的那条。

经过这样的筛选后,就会为后面的路径寻找提供方便,从而减少回溯次数。

棋盘中马的遍历采用数组进行存储,同时因为有回溯,所以采用栈的方法,并且为了最后打印方便,采用的是顺序栈的方法。

同时还有八个方向的数组,和为栈设计的每个点周围的八个方向那些可以走的数组。

2. 基本要求棋盘有10行9列,利用chess来表示一个棋盘,chess[i][j]=0或1;其中:0表示通路,1表示不通,当从某点向下试探时,中间点的8个方向可以试探;棋盘采用数组形式,并且这里的数组比棋盘的数组规模稍大,因为为了保证边缘点也有八个方向可以走,使问题能够简单化,不用再判断当前点的试探方向有几个。

马踏棋盘

马踏棋盘
if(m_curcal >= 64) {
if(abs((m_curstep.stepx - m_first.stepx) * (m_curstep.stepy - m_first.stepy)) == 2)
return 1;
}
return 0;
if(cantry(m,n)){
step.stepid = m_curcal + 1;
step.stepx = m;
step.stepy = n;
m_stlstack.push(step);
}
}
m = m_curstep.stepx - 1;
if(m_firstfree > 1) {
m_firstfree --;
return 1;
}else{
return 0;
}
}
}
return 1;
}
BOOL chess_plan::calover()
{
//return ((m_curcal >= 64) ? 1 : 0);
m_firstfree = a;
return m_firstfree;
}
BOOL chess_plan::cantry(int x,int y)
{
if(m_curcal < 63) {
if(abs((x - m_first.stepx) * (y - m_first.stepy)) == 2) {
#include <iostream>
#include <stack>
using namespace std;

马踏棋盘非递归算法

马踏棋盘非递归算法

#include <iostream.h>struct point{int x,y;//马的位置int dir;//这一次马行走的方向};struct stack{point p[64];//存储马的位置,方便回溯};int board [8][8];int Htry1[8]={-2,-1,1,2,2,1,-1,-2};int Htry2[8]={1,2,2,1,-1,-2,-2,-1};bool chech[8][8]={0};//标记位置是否已经被占用int main(){int i,j;int top=0;int z;cout<<"请输入马的初始位置";cin>>i;cin>>j;stack sta;sta.p[top].x=i;sta.p[top].y=j;board [i][j]=top;chech [i][j]=true;int nx;int ny;for(int u=0;u<64;u++)sta.p[u].dir=0;//把每个结点的dir清零for(z=0;;){if(sta.p[top].x+Htry1[z]>=0&&sta.p[top].x+Htry1[z]<8&&sta.p[top].y+Htry2[z]>=0&&sta.p[top].y+Htry2[z]<8&&!chech [sta.p[top].x+Htry1[z]][sta.p[top].y+Htry2[z]]//检查要走的下个位置是否可行){nx=sta.p[top].x+Htry1[z];ny=sta.p[top].y+Htry2[z];sta.p[top].dir=z;top++;sta.p[top].x=nx;sta.p[top].y=ny;board [nx][ny]=top;chech [nx][ny]=true;z=-1;}else if(z==7)//如果不可行,而且是最好一次检查{ chech [sta.p[top].x][sta.p[top].y]=false;top--;while(1){z=sta.p[top].dir;if(z!=7)break;else{ chech [sta.p[top].x][sta.p[top].y]=false;top--;}}}if(top==-1||top==63)break;//如果回溯到-1,或者栈满,则退出循环 z++;}for(i=0;i<8;i++){for(j=0;j<8;j++)cout<<board [i][j]<<" ";cout<<endl;}return 1;}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档