关于回溯与走八方

  有个汉子,和一匹马,从5*5的棋盘一角出发,要走完棋盘的每一个角落,对没错,每一个角落。输出所有的走法。如:

    输出格式示例:
      1    16   21   10   25
      20  11   24   15    22
      17  2     19   6     9
      12  7     4     23   14
      3   18    13   8     5
  示例中的数字代表的是所走的步数。

  首先,我们知道马在棋盘上正常情况下共有八个可走的方向,这八个方向会在回溯算法中多次调用,所以我们可以用两个数组来储存它们。然后就是进行遍历,判断按照该方向下一步是否会越界,若不会越界,则 判断该方向下一步是否已经走过,若走过(标志变量被修改为了所走的步数),则换一个方向,若没走过(标志变量为0),则将该位置标记。然后重复该过程,若遍历了所有的方向,不用小子说大家也懂,那就回溯一步。

  来看看代码:

 1 #include<stdio.h>
 2 int sum=0;
 3 int board[5][5]={0};
 4 int x[8]={1,2,2,1,-1,-2,-2,-1};//储存八个方向
 5 int y[8]={2,1,-1,-2,2,1,-1,-2};//储存八个方向
 6 void out();//输出函数
 7 void f(int k,int a,int b);//k统计步数,a为上一位置的横坐标,b为上一位置的纵坐标
 8 int main()
 9 {
10     board[0][0]=1;
11     f(2,0,0);
12     return 0;
13 }
14 void f(int k,int a,int b)
15 {
16     int i;
17     for(i=0;i<=7;i++)
18     {
19         if( (a+x[i]>=0) && (a+x[i]<=4) //判断该方向下一步的横坐标是否越界
20          && (b+y[i]>=0) && (b+y[i]<=4) /*判断该方向下一步的纵坐标是否越界*/)
21         {
22             if(board[a+x[i]][b+y[i]]==0)
23             {
24                 board[a+x[i]][b+y[i]]=k;
25                 if(k==25)
26                     out();
27                 else
28                     f(k+1,a+x[i],b+y[i]);
29                 board[a+x[i]][b+y[i]]=0;
30             }
31         }
32     }
33 }
34 void out()
35 {
36     int i,j;
37     sum++;
38     printf("第%d种走法:\n",sum);
39     for(j=0;j<=4;j++)
40     {
41         for(i=0;i<=4;i++)
42         {
43             printf("%d\t",board[i][j]);
44         }
45         printf("\n");
46     }
47 }
48 //注意,若按照该代码进行,将不能达成题目的输出所有解的要求,若想达成此要求,则需要同学自行使用重定向(freopen)输出

  代码如有不足之处,欢迎指出!

时间: 2024-08-04 20:17:56

关于回溯与走八方的相关文章

ACM:回溯法,八皇后问题,素数环

(一)八皇后问题 (1)回溯法 #include <iostream> #include <string> #define MAXN 100 using namespace std; int tot = 0, n = 8; int C[MAXN]; void search(int cur) { if(cur == n) ++tot; //递归边界,只要走到了这里,所有皇后必然不冲突 else for(int i = 0; i < n; ++i) { int ok = 1; C

回溯算法(八皇后问题)

八皇后问题 在国际象棋中,皇后是最强大的一枚棋子,可以吃掉与其在同一行.列和斜线的敌方棋子. 将八个皇后摆在一张8*8的国际象棋棋盘上,使每个皇后都无法吃掉别的皇后,一共有多少种摆法? 程序实现 程序摘自回溯法与八皇后问题 #include<iostream> #include<math.h> using namespace std; int n=8; int total=0; int *c=new int(n); //下标为行数,存的数为列数 bool is_ok(int row

【基础算法】回溯法与八皇后问题

在国际象棋中,皇后是最强大的一枚棋子,可以吃掉与其在同一行.列和斜线的敌方棋子.比中国象棋里的车强几百倍,比她那没用的老公更是强的飞起(国王只能前后左右斜线走一格).上图右边高大的棋子即为皇后. 八皇后问题是这样一个问题:将八个皇后摆在一张8*8的国际象棋棋盘上,使每个皇后都无法吃掉别的皇后,一共有多少种摆法?此问题在1848年由棋手马克斯·贝瑟尔提出,岂止是有年头,简直就是有年头,82年的拉菲分分钟被秒的渣都不剩. 八皇后问题是典型的回溯法解决的问题,我们以这个问题为例介绍回溯法. 所谓回溯法

回溯法:八皇后问题

八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行.纵行或斜线上.八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成n.当且仅当 n = 1 或 n ≥ 4 时问题有解. 这个问题简化描述就是:在8x8的棋盘上放8颗子,要求它们[不在同一行][不在同一列][不在同一斜线]上. 我们可以定义一个数组position[8],positon

【回溯法】八皇后问题(递归和非递归)

先贴代码,分递归回溯法和非递归回溯法 递归回溯法,代码如下: // test.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> #include <stdio.h> using namespace std; int a[9] = {0}; int n = 8; int count = 0; bool check

回溯算法解八皇后问题(java版)

八皇后问题是学习回溯算法时不得不提的一个问题,用回溯算法解决该问题逻辑比较简单. 下面用java版的回溯算法来解决八皇后问题. 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 思路是按行来规定皇后,第一行放第一个皇后,第二行放第二个,然后通过遍历所有列,来判断下一个皇后能否放在该列.直到所有皇后都放完,或者放哪

回溯法与八皇后问题

tail recursion 函数在调用的时候,会提前创建一个栈空间,给传递的参数也分配空间,当函数结束返回上层函数的时候,一些局部变量需要从栈中弹出并恢复到调用子函数之前的值,返回到上一个函数调用子函数之前的现场.如果是尾递归,从子函数返回的时候这个函数同时也会结束了,所以没有必要恢复一些局部变量,直接把局部变量的栈空间删除.因此一个尾递归的函数根本不需要使用栈来给子函数变量空间,可以直接使用当前变量的值为新参数的值. backtracking 八皇后问题 用一个类Queens表示棋盘上现在的

回溯法解决八皇问题

把八个皇后放在一个8*8的棋盘上面,要求同一行.同一列.同一对角线不能有两个皇后. 思路:关键在于判定两个皇后是否在同一行.同一列或同一对角线上.这里,棋盘下标从1开始算起.观察发现:若是在同一行,则行号相同:若在同一列,则列号相同:若在同一“/”对角线,则行列值之和相同:若是在同一“\”对角线,则行列值之差相同.考虑到每行仅有一个皇后,设一维数组a[1...8]表示皇后的位置:第i行第j列放置皇后,则a[i]=j,即下标是行数,值是列数.判断皇后是否安全,即检查同一列.同一对角线是否已经有皇后

C++回溯法走迷宫

#include <iostream> #include <iomanip> #include <cstdlib> using namespace std; #define MaxSize 100 int maze[10][10] = //定义一个迷宫,0表示通道,1表示墙 { {1,1,1,1,1,1,1,1,1,1}, {1,0,0,1,1,0,0,1,0,1}, {1,0,0,1,0,0,0,1,0,1}, {1,0,0,0,0,1,1,0,0,1}, {1,0,