题解洛谷P1002(c++解法)过河卒

题目传送门

大家看到这题一般会用搜索来做,也许调试时全过,但运行时当n、m=15时就会超时
其实,本题稍加分析就能发现,要到达棋盘上的一个点,只能从左边或上面过来(以下称为左点和上点)
所以,根据加法原理,到达某一点的路径数目,就等于到达其相邻的上点和左点的路径数目之和,因此我们可以使用逐列(或逐行)递推的方法来求出从起点到终点的路径数目
障碍点(马的控制点)也完全适用,只要将到达该店的路径数目设置为0即可
递推关系式如下:

a[i][j]=a[i-1][j]+a[i][j-1]

代码如下

#include
#include
#include
#include
#define MAXN 110
bool b[MAXN][MAXN];
long long a[MAXN][MAXN];
int dx[8]={2,1,-1,-2,-2,-1,1,2};
int dy[8]={1,2,2,1,-1,-2,-2,-1};
int n,m,x,y;
using namespace std;
int main(){
    cin>>n>>m>>x>>y;
    memset(b,0,sizeof(b));
    b[x][y]=1;
    for(int i=0;i<=7;i++){
         if(x+dx[i]>=0&&x+dx[i]<=n&&y+dy[i]>=0&&y+dy[i]<=m){
            b[x+dx[i]][y+dy[i]]=1;
         }
    }
    int k=0;
    while(!b[k][0]&&k<=n){
        a[k++][0]=1;
    }
    int l=0;
    while(!b[0][l]&&l<=m){
        a[0][l++]=1;
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(b[i][j]){
                a[i][j]=0;  //g[i][j]=1
            }
            else{
                a[i][j]=a[i-1][j]+a[i][j-1];  //i>0且j>0且g[i][j]=0
            }
        }
    }
    cout<<a[n][m];
    return 0;
}

你可能感兴趣的:(题解洛谷P1002(c++解法)过河卒)