题目链接:洛谷-过河卒
题目描述
棋盘上 A 点有一个过河卒,需要走到目标 B 点。卒行走的规则:可以向下、或者向右。同时在棋盘上 C 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。
棋盘用坐标表示,A 点 (0, 0)、B 点 (n,m),同样马的位置坐标是需要给出的。
现在要求你计算出卒从 A 点能够到达 B 点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
输入格式
一行四个正整数,分别表示 B 点坐标和马的坐标。
输出格式
一个整数,表示所有的路径条数。
输入输出样例
输入
6 6 3 3输出
6说明/提示
对于 100% 的数据,1≤n,m≤20,0≤ 马的坐标≤20
题目分析
通过题目可知,马所在的点,经过计算即可得出马控制的点。将其标记出来。
void search(long long x,long long y){ ma[x][y]=1; ma[x-1][y-2]=1; ma[x-2][y-1]=1; ma[x-2][y+1]=1; ma[x-1][y+2]=1; ma[x+1][y-2]=1; ma[x+2][y-1]=1; ma[x+2][y+1]=1; ma[x+1][y+2]=1; }
通过百度可得,到棋子该点(x,y)的路径条数是由该点左边的点(x-1,y)加上该点上边的点(x,y-1)相加所得。在x轴上的点由于无上方的点那么就与左边的点的路径条数相同,由此可得,在x轴上的点的路径条数均为1条。同理,在y轴上的点的路径条数也都为1条。那么设到初始点的路径条数为一就可以得知到任意一个点的路径条数是几条。在判断该点并非马控制的点之后进行累加计算。
核心代码
void judg(int x,int y){ for(int i = 0; i <= x; ++i) { for(int j = 0; j <= y; ++j) { if(ma[i][j]==0) //该点没被马控制 { if(i == 0 && j == 0) //递推边界1 f[0][0]=1 f[0][0] = 1; else if(i == 0 && j > 0)//x=0时到该点的路径条数就是到其左边点的路径条数; f[0][j] = f[0][j - 1]; else if(i > 0 && j == 0)//y=0时到该点的路径条数就是到其右边点的路径条数; f[i][0] = f[i - 1][0]; else//由于只能向下或者向右,所以到该点的路径条数就是到其左边点路径条数与上边点路径条数之和 f[i][j] = f[i - 1][j] + f[i][j - 1]; } } } cout << f[x][y] << endl; }
完整代码如下:
#include <cstdio>
#include <iostream>
using namespace std;
long long a,b,n,m,f[25][25];
bool ma[23][23];
int num=0;
void search(long long x,long long y){
ma[x][y]=1;
ma[x-1][y-2]=1;
ma[x-2][y-1]=1;
ma[x-2][y+1]=1;
ma[x-1][y+2]=1;
ma[x+1][y-2]=1;
ma[x+2][y-1]=1;
ma[x+2][y+1]=1;
ma[x+1][y+2]=1;
}
void judg(int x,int y){
for(int i = 0; i <= x; ++i)
{
for(int j = 0; j <= y; ++j)
{
if(ma[i][j]==0) //该点没被马控制
{
if(i == 0 && j == 0) //递推边界1 f[0][0]=1
f[0][0] = 1;
else if(i == 0 && j > 0)//x=0时到该点的路径条数就是到其左边点的路径条数;
f[0][j] = f[0][j - 1];
else if(i > 0 && j == 0)//y=0时到该点的路径条数就是到其右边点的路径条数;
f[i][0] = f[i - 1][0];
else//由于只能向下或者向右,所以到该点的路径条数就是到其左边点路径条数与上边点路径条数之和
f[i][j] = f[i - 1][j] + f[i][j - 1];
}
}
}
cout << f[x][y] << endl;
}
int main(){
scanf("%lld %lld %lld %lld",&n,&m,&a,&b);
search(a,b);
judg(n,m);
return 0;
}
计算机204 nht