问题描述:
在m行n列的棋盘上有一个中国象棋的马,马走日字且只能向右走。请找到可行路径的条数,使得马从棋盘的左下角(1,1)走到右上角(m,n)。
算法思路:由于马只能向右走,所以只有四个方向,用一个数组a存放马可以走的方向,并用step数组记录马走的路径,马每走一步后就判断当前步骤是否合法(test函数),不合法就回退到上一步,然后在走另一个方向,如果合法,就执行下一步(next函数),以此类推,不断回溯,当走到棋盘的右上角时,算法结束,从而找到一条合适的路径,并记录路径的条数。
算法输入:马走的方向i(0~3),棋盘大小m行n列,当前位置坐标x,y,存放路径数组step,存放马走的方向的数组a,路径条数num_methods。
算法输出:数组step存放的路径和路径条数num_methods。
代码示例:
#include <iostream>
#include <string.h>
#include <vector>
using namespace std;
bool test(int i, int m, int n, int x, int y)
{
switch (i)
{
case 0:
{
if (x <= n && y <= m)
break;
}
case 1:
{
if (x <= n && y <= m)
break;
}
case 2:
{
if (x <= n && y <= m)
break;
}
case 3:
{
if (x <= n && y <= m)
break;
}
}
if (x > n || y > m || x < 1 || y < 1) return true;
return false;
}
void next(int i, int m, int n, int x, int y, vector<int> step, string a[], int& num_methods);
void fun(int m, int n, int x, int y, vector<int> step, string a[], int& num_methods)
{
for (int i = 0; i < 4; i++)
{
if (test(i, m, n, x, y))
{
continue;
}
else
{
next(i, m, n, x, y, step, a, num_methods);
}
}
}
void next(int i, int m, int n, int x, int y, vector<int> step, string a[], int& num_methods)
{
switch (i)
{
case 0:
{
x = x+1;
y = y+2;
break;
}
case 1:
{
x =x+ 2;
y =y+ 1;
break;
}
case 2:
{
x =x+2;
y =y-1;
break;
}
case 3:
{
x = x+1;
y = y-2;
break;
}
}
step.push_back(i);
if (x == n && y == m)
{
cout << "一种方法:" << endl;
for (int j = 0; j < step.size(); j++)
{
cout<<a[step[j]]<<endl;
}
cout << "方法结束:" << endl;
num_methods++;
return;
}
fun(m, n, x, y, step, a, num_methods);
}
int main()
{
int m,n,num_methods = 0;
cout<<"请输入棋盘的规模:"<<endl;
cin>>m>>n;
string a[] = { "x+1,y+2","x+2,y+1","x+2,y-1","x+1,y-2" };
vector<int> step;
fun(m, n, 1, 1, step, a, num_methods);
cout<<endl;
cout << "方法总数" << num_methods << endl;
return 0;
}
运行结果: