c语言洛谷过河卒

/*
用了动态规划(dp)的方法做出这道题
巧妙地构成了下标是坐标 值是路径的总条数
刻画动态过程->列出表达式 (边界 普通)
 
*/
#include <stdio.h>
int main()
{
    long long  n,m,x,y,i,j;  //要用long long  下面同理  
    scanf("%d %d %d %d",&n,&m,&x,&y);


    long long  dp[n+100][m+100];  //这个数组的i和j(下标)  是坐标 这个数组的值 就是到这个点路的总和  所以 只需要输出dp[n][m]就是到达点B的路径总数。 
    for(i=0;i<=n;i++)
    {
        for(j=0;j<=m;j++)
        {
            dp[i][j]=1;           //初始化到达每一个点的路径总数都为1 (画一个正方形想到的 到达正方形右下角的那个点就是1+1 也就是左下脚的1 加上右上角的1) 
            
        }
    
    }
    
    //对所有马的控制点初始化为0 因为不能到它这个点上 所以到这个点上的路的总和为0 
    //哦对了 这个if语句是判断它有没有出这个地图 如果没有再初始化为0 如果出去了 就不用管了 数组都越界了屁 
    dp[x][y]=0;                   //上面已经全部初始化为1 现在要对马的特殊控制点 初始化为0 保证 它这里是行不通的 比如 在马的控制点的下方 它路径的总数就是0+此点左边的点的数 

    if(x-1>=0 && y-2>=0)//P5
    {
        dp[x-1][y-2]=0;
    }

    if(x-1>=0 && y+2<=n)//P8
    {
        dp[x-1][y+2]=0;
    }

    if(x-2>=0 && y-1>=0)//P6
    {
        dp[x-2][y-1]=0;
    }
    if(x-2>=0 && y+1<=n)//P7
    {
        dp[x-2][y+1]=0;
    }
    if(x+1<=m && y-2>=0)//P4
    {
        dp[x+1][y-2]=0;
    }
    if(x+1<=m && y+2<=n)//P1
    {
        dp[x+1][y+2]=0; 
    }
    if(x+2<=m && y-1>=0)//P3 
    {
        dp[x+2][y-1]=0;
    }
    if(x+2<=m && y+1<=n)//P2
    {
        dp[x+2][y+1]=0;
    }
    

    
    for(j=0;j<=m;j++)  //我是从左向右的习惯 所以 先是将列数固定 循环所有行数 也就是 一列一列的填满整个地图  也可以从上到下 那么就是正常的i在外面 j在里面 只不过我不习惯 
    {
        for(i=0;i<=n;i++)
        {
            if(dp[i][j]==0)   //遇见马的控制点就跳过 不能改变马控制点为0 
            continue;
            
            else if (j==0 && i==0)   //遇见原点(0.0)也跳过 没意义 
            continue;
            
            else if(j==0)  //这个是在边界 也就是第一列 也就是x轴 
            dp[i][j] = dp[i-1][j]; //这就是在x轴上点的公式 它没有左边的点 所以     dp[i][j] = dp[i-1][j]; 到达这个点的路径总数 就等于到达它上一个点的路径总数 
             
            else if(i==0)   //同理 这是在y轴上的点的公式 等于它左边的点的路径总数 
            dp[i][j] = dp[i][j-1];
            
            else   //这是一个普通的点 所以 这个点就等于 它左面的点 加上它上面的点 
            dp[i][j] = dp[i-1][j] + dp[i][j-1];
            
        
        }
        
    }


    printf("%d",dp[n][m]);  //最后输出 B点坐标就可以 就代表着到达B点的路径总数 你运行调试的时候 可以用双层循环将所有的点的情况打印出来 
     
   
    return 0;
    
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值