小编建议,如果对此题不太明白的童鞋,可以把解题答案一个一个默念一遍,边念边想,这样效果可能会好一点。
看到这个问题,我们可以找到这么一个突破口
找一个特例,记红点所经过的次数为p,左绿点所经过的次数为g1,上绿点所经过的次数为g2
因为所经过的次数等于通过的路径数
所以到达红点的路径p=g1+g2
以次类推,整道题目的大致思路也就是这样子的
解题思路:
①将所有不能走的点全部标记起来
②p=g1+g2(用for循环)得出每个点有多少条路经过
#include<iostream>
//首先将不能走的点全部赋值-1,或0
//最后将上方和左方的数加起来,最后得到的就是点b对应的路径数
using namespace std;
int path[][2] = { {1,2},{1,-2},{2,1},{2,-1},{-1,2},{-1,-2},{-2,1},{-2,-1} };
int mx, my, bx, by; //全局变量自动赋值0
typedef long long ll;
ll pan[25][25]; //题目中如果有说结果可能很大,则选用long long或者unsigned long long
void judge()
{
pan[mx][my] = -1; //将马自身的位置记为-1
for (int i = 0; i < 8; i++)
{
if(mx + path[i][0]>=0&&my+path[i][1]>=0)
pan[mx + path[i][0]][my+path[i][1]] = -1; //将马所能到达的位置记为-1(在x轴和y轴正半轴)
}
for (int j = 0; j <= bx; j++)
{
if (pan[j][0] == -1) //将y=0,即x轴上的点不是-1的就赋值为1
break;
else
pan[j][0] = 1;
}
for (int j = 0; j <= by; j++)
{
if (pan[0][j] == -1) //这里是对y轴上的点的操作,与上述一样
break;
else
pan[0][j] = 1;
}
}
void submit()
{
cin >> bx >> by >> mx >> my;
judge();
for (int i = 1; i <= bx; i++)
//因为后面要判断点的左方和上方,要减一,所以i和j不能从0开始
{
for (int j = 1; j <= by; j++)
{
if (pan[i][j] == -1) //小编错在了这一步,粗心把双等号写成了=
//这一步不要忘记,要在判断每个点的值不为-1后才可进行后面的左上相加
//因为这个点已经不能走了,所以不能其它数相加来表示路径数
continue;
else
{
//分为左方和上方,将那些赋值后不为-1的相加起来,得到此点所经过的次数
if (pan[i - 1][j] > 0)
pan[i][j] += pan[i - 1][j];
if (pan[i][j - 1] > 0)
pan[i][j] += pan[i][j - 1];
}
}
}
cout << pan[bx][by] << endl; //输出B点所经过的次数
}
int main()
{
submit();
}
如果要将整个棋盘打印出来的话,则需要在void submit里面的两个for循环后面加以下代码:`
for (int i = 0; i <= bx; i++) //等号要有,因为棋盘(0,0)时有,(bx,by)也有,pan[][]就是表示棋盘的数组
{
for (int j = 0; j <= by; j++)
{
cout << "\t" << pan[i][j];
}
cout << endl; //注意要加上去,每打印完一行就换行
}