马的遍历——搜索与回溯

题目描述 Description

中国象棋半张棋盘如图所示。马自左下角往右上角跳。今规定只许往右跳,不许往左跳。比如图4(a)中所示为一种跳行路线,并将所经路线打印出来。

输入输出格式 Input/output

输入格式:

输出格式:

第一行:一个整数total表示第几种跳法

第二行:0,0-->2,1-->3,3-->1,4-->3,5-->2,7-->4,8

输入输出样例 Sample input/output

样例测试点#1

输入样例:

输出样例:

1

0,0-->2,1-->3,3-->1,4-->3,5-->2,7-->4,8…

【算法分析】

如图4(b),马最多有四个方向,若原来的横坐标为j、纵坐标为i,则四个方向的移动可表示为:

1:  (i,j)→(i+2,j+1);  (i<3,j<8)

2:  (i,j)→(i+1,j+2);  (i<4,j<7)

3:  (i,j)→(i-1,j+2);  (i>0,j<7)

4:  (i,j)→(i-2,j+1);  (i>1,j<8)

搜索策略:

S1:A[1]:=(0,0);

S2:从A[1]出发,按移动规则依次选定某个方向,如果达到的是(4,8)则转向S3,否则继续搜索下一个到达的顶点;

S3:打印路径。

思路:可以用一个数组存路径,循环四次(四种移动规则)

         判断条件是否成立(是否在格子内)

         成立,保存当前马的位置,再判断是否跳到头了,是就输出(传入输出函数),反之则继续寻找

代码如下:

 1 #include <stdio.h>
 2 int a[100][100],total=0;//路径总数和路径
 3 int x[4]={2,1,-1,-2},y[4]={1,2,2,1};//四种移动规则
 4 int print(int ii)
 5 {
 6     int i;
 7     total++;
 8     printf("%d\n",total);
 9     for(i=0;i<ii;i++)
10     {
11         printf("%d,%d-->",a[i][1],a[i][2]);
12     }
13     printf("4,8\n");
14 }
15 int search(int i)
16 {
17     int j;
18     for(j=0;j<=3;j++)
19     {
20         if(a[i-1][1]+x[j]>=0&&a[i-1][1]+x[j]<=4&&a[i-1][2]+y[j]>=0&&a[i-1][2]+y[j]<=8) //判断马是否越界
21         {
22             a[i][1]=a[i-1][1]+x[j];//保存当前马的位置
23             a[i][2]=a[i-1][2]+y[j];//保存当前马的位置
24             if(a[i][1]==4&&a[i][2]==8) print(i);//到头了,输出
25             else search(i+1);//否则,下一步
26         }
27     }
28 }
29 int main()
30 {
31     a[1][1]=0;
32     a[1][2]=0;
33     search(2);
34     return 0;
35 }
时间: 2024-10-25 02:41:04

马的遍历——搜索与回溯的相关文章

sicily 1152 简单马周游 深度优先搜索及回溯算法

1152. 简单的马周游问题 Constraints Time Limit: 1 secs, Memory Limit: 32 MB , Special Judge Description 在一个5 * 6的棋盘中的某个位置有一只马,如果它走29步正好经过除起点外的其他位置各一次,这样一种走法则称马的周游路线,试设计一个算法,从给定的起点出发,找出它的一条周游路线. 为了便于表示一个棋盘,我们按照从上到下,从左到右对棋盘的方格编号,如下所示: 1     2     3       4    

马的遍历问题

题意例如以下: 马的遍历问题.设计程序完毕例如以下要求: 在中国象棋棋盘上,对任一位置上放置的一个"马". 均能选择一个合适的路线,使得该棋子能按象棋的规则 不反复地走过棋盘上的每一位置. 思路:这是一个DFS搜索,然后没有使用另外的数组来标记某一位置是否已经被走过,而是直接使用存步数的数组num[][]来作为标记数组! 然后我使用了两个数组作为方向坐标,以便能让马移动,同一时候也能记录马所在位置的坐标!(马是能够从8个移动方向中选择的!) 代码还是非常好理解的! 至于棋盘的规格能够自

马的遍历

题目链接 首先,这是一道水题.(虽然我提交了四次才A掉) 思路是很简单的.马的遍历,经典中的经典,一想就是搜索.但流传较广的是DFS,第一直觉也是DFS.可是,一看题,求马到各点的最短路,是求最优解,且是各个点,自然想到了BFS. BFS的简单思路,将矩阵每个点 原文地址:https://www.cnblogs.com/qing1/p/11066106.html

数据结构-6-深度广度遍历搜索原理详解

深度广度遍历搜索的定义想必大家都能熟练的掌握了,下面我就通过一个图的实例,把应用的代码直接贴上供大家参考,以后可以直接借鉴或者使用. #include <iostream> #include <string> #include "Queue.h" using namespace std; //图的邻接矩阵存储表示 #define INFINITY INT_MAX #define MAX_VERTEX_NUM 20 typedef enum {DG, DN, UD

P1443 马的遍历

P1443 马的遍历 题目描述 有一个n*m的棋盘(1<n,m<=400),在某个点上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步 输入输出格式 输入格式: 一行四个数据,棋盘的大小和马的坐标 输出格式: 一个n*m的矩阵,代表马到达某个点最少要走几步(左对齐,宽5格,不能到达则输出-1) 输入输出样例 输入样例#1: 3 3 1 1 输出样例#1: 0 3 2 3 -1 1 2 1 4 #include<iostream> #include<cstdio>

使用Boost Regex 的regex_search进行遍历搜索

在regex_search函数中,会将找到的第一个匹配结果保存到一个smatch类中. 然而如果搜索字符串中有多个匹配结果,则需要自己实现了. 在smatch中,有两个成员,官方文档如下: iterator first: An iterator denoting the position of the start of the match. iterator second An iterator denoting the position of the end of the match. 所以,

一本通搜索与回溯例题5.2

[题目描述] 排列与组合是常用的数学方法,其中组合就是从n个元素中抽出r个元素(不分顺序且r≤n),我们可以简单地将n个元素理解为自然数1,2,…,n,从中任取r个数. 现要求你用递归的方法输出所有组合. 例如n=5,r=3,所有组合为: 1 2 3   1 2 4   1 2 5   1 3 4   1 3 5   1 4 5   2 3 4   2 3 5   2 4 5   3 4 5 [输入] 一行两个自然数n.r(1<n<21,1≤r≤n). [输出] 所有的组合,每一个组合占一行且

Ka的回溯编程练习 Part3|马的遍历

1 #include <stdio.h> 2 int board[100][3]={0},totally=0; 3 int x[4]={2,1,-1,-2},y[4]={1,2,2,1}; 4 void o(int k) //这个输出函数需要借助回溯中n的值来完成输出 5 { 6 totally++; 7 printf("%d:",totally); 8 int r; 9 for(r=1;r<=k-1;r++) 10 printf("|%d,%d|->

Ka的回溯编程练习 Part5|跳马,又名马的遍历2

1 #include <stdio.h> 2 int TheEarthLand[6][6]={0}; 3 int HowToGoX[]={0,1,2,2,1,-1,-2,-2,-1}; 4 int HowToGoY[]={0,-2,-1,1,2,2,1,-1,-2}; 5 int total=0; 6 void op() 7 { 8 total++; 9 printf("<Way%d>:\n",total); 10 int i,j; 11 for(i=1;i&l