具体代码:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#define true 1
#define false 0
#define MAX 20
//num是有多少走到终点的方式
//min记录到终点的最小步数
int min = 32767;
//step经过的点数数量
int step = 1;
//最大棋盘的数组并初始化表示未走过
int a[MAX][MAX];
//象棋挪动的方式
int move[8][2] = { {2,-1}, {1,-2}, {-1,-2}, {1,2}, {2,1}, {-2,-1}, {-2,1}, {-1,2} };
//广度优先遍历,输入出发点和结束点
void dfs(int x, int y, int x2, int y2)
{
//x1,y1为暂时的位置
int i, x1, y1;
//当步数大于最小值的情况就不需要继续往下了
if (step > min) return;
//当遍历了全部的结点,便可返回
if (x == x2 && y == y2)
{
//成功递归一次证明有一种走完全部节点的可能性
if (step <= min) min = step;
}
else
//按照八种不同的方向走的情况
for (i = 0; i < 8; i++)
{
//每次递归就移动一次
x1 = x + move[i][0];
y1 = y + move[i][1];
//不能出棋盘,并且落点未被选中过
if (x1 >= 0 && x1 < 10 && y1 >= 0 && y1 < 9 && a[x1][y1] == 0)
{
//选中该落点
a[x1][y1] = true;
//落点数+1
step++;
//递归调用
dfs(x1, y1, x2, y2);
//当一次结束递归时,让步数一步步返回至原点,并且开始下一种可能性的递归
step--;
//将上一次递归选中的点再依次设置为未选中
a[x1][y1] = false;
}
}
}
int main()
{
//输入的的第1行是一个整数n,表示以后会有n行数据。
// 从第2行开始,每行有4个整数,前2个数表示起点坐标,后2个数表示终点坐标。
int T, x, y, x2, y2;
scanf("%d", &T);
while (T--)
{
step = 0;
min = 32767;
scanf("%d %d %d %d", &x, &y, &x2, &y2);
memset(a, 0, sizeof(a));
a[x][y] = 1;
dfs(x, y, x2, y2);
printf("%d\n", min);
}
return 0;
}
画图理解:最小步数路径不唯一
![](https://i-blog.csdnimg.cn/direct/4dfaec69dc5542d48690fab85c65cc3e.png)
![](https://i-blog.csdnimg.cn/direct/2d32fdd96d32499f812daec95c073d5e.png)