洛谷 P1002 过河卒

原创 2017年01月04日 00:21:13

题目描述

棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。

棋盘用坐标表示,A点(0, 0)、B点(n, m)(n, m为不超过20的整数),同样马的位置坐标是需要给出的。

现在要求你计算出卒从A点能够到达B点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。

输入输出格式

输入格式:

一行四个数据,分别表示B点坐标和马的坐标。

输出格式:

一个数据,表示所有的路径条数。

输入输出样例

输入样例#1:
6 6 3 3

输出样例#1:
6

解题思路

这题可以自己在草稿纸上数一下,到一个点到底有几种方法,然后归纳一下,即可得到:到达(x,y)的方法数等于到达(x-1,y)的方法数+到达(x,y-1)的方法数,然后不能去的地方特判一下,设成0,还有最左边一列和最上边一行特殊处理一下(见下),然后就没有然后了。
(粘一个烂大街但又很好懂的解析)对本题稍加分析就能发现,到达棋盘上的一个点,只能从左边过来(我们称之为左点)或是从上面过来(我们称之为上点)。根据加法原理,到达某一点的路径条数,就等于到达其相邻的上点或左点的路径数目总和。因此我们可以使用逐列(逐行)递推的方法来求出从起点到终点的路径数目。障碍点(马的控制点)也完全适用,只要将到达该点的路径数目设置为0即可。
假设用F[I,J]到达点(I,J)的路径数目用G[I,J]表示点(I,J)是否为对方马的控制点,G[I,J]=0表示不是对放马的控制点,G[I,J]=1表示是对方马的控制点。则,我们可以得到如下的递推关系式:
F[I,J]=0{G[I,J]=1}
F[I,0]=F[I-1,0]{I>0,G[I,0]=0}
F[0,J]=F[0,J-1]{J>0,G[0,J]=0}
F[I,J]=F[I-1,J]+F[I,J-1]{I>0,J>0,G[I,J]=0}
上述递推式边界是:F[0,0]:=1。考虑到最大情况下:n=20,m=20,路径条数可能会出现超出长整型范围,所以要用int64或comp类型计数或者高精度运算(是不是要开一个三维数组呢)。

#include<stdio.h>//这个编辑器的缩进比较怪异
short g[25][25];
int main()
{
    long long bn,bm,n,m;
    long long f[25][25];
    scanf("%lld%lld%lld%lld",&bn,&bm,&n,&m);
    for(int i=0;i<25;i++)
        for(int j=0;j<25;j++)
            g[i][j]=f[i][j]=0;
    f[0][0]=g[n][m]=1;
    if(n>=1&&m>=2) g[n-1][m-2]=1;
    if(n>=2&&m>=1) g[n-2][m-1]=1;
    if(n>=1) g[n-1][m+2]=1;
    if(n>=2) g[n-2][m+1]=1;
    if(m>=2) g[n+1][m-2]=1;
    if(m>=1) g[n+2][m-1]=1;//这一排if是针对数组越界的,还可以把整个棋盘全体下移再右移两格
    g[n+1][m+2]=1;
    g[n+2][m+1]=1;
    for(int i=1;i<25;i++)
    {
        if(!g[i][0])f[i][0]=f[i-1][0];
        if(!g[0][i])f[0][i]=f[0][i-1];
    }//边界如果为零,那它后面的都不可到达,我傻傻的把后面的照样赋值为1,0~60分不等
    
    for(int i=1;i<=bn;i++)
    {
        //printf("%6lld (%d %d)  ",f[i][0],i,0);
        for(int j=1;j<=bm;j++)
        {
            if(g[i][j])
                f[i][j]=0;
            else
                f[i][j]=f[i-1][j]+f[i][j-1];
            //printf("%6lld (%d %d)  ",f[i][j],i,j);
        }
        //printf("\n");
    }
    printf("%lld",f[bn][bm]);
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载 举报

相关文章推荐

洛谷 P1002 过河卒

题目描述 棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。...

【洛谷】P1002-过河卒

【洛谷】P1002-过河卒 题目描述 棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制...

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

【搜索】洛谷 P1002 过河卒

题目描述棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。棋盘...

洛谷P1002 Codevs1011 过河卒 --2002年NOIP全国联赛普及组 dp递推

洛谷 P1002 过河卒 双倍经验 三倍经验整张图向右下移动了 3 个,以防判断马不能走的点时不越界。 本来不想暴力更改马不能走的点的,发现定义数组for 更麻烦……dp的初始化:最上面一行 和...

洛谷1052 过河

原题地址 https://www.luogu.org/problem/show?pid=1052 题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧。在桥上有一些石子,青蛙很讨厌踩...

洛谷P1052 过河

读完题目想到的应该是动态规划,状态转移方程为f[i]=min(f[i],f[j]+v[i]) (v[]表示当前点的石头,j∈[i-s,i-t]),但是转移的是每个点,而数据范围有1000000000那...

【洛谷P1052】过河

很经典的一道题,也是很著名的一道状态压缩DP,十一的时候lch讲过但是没听懂= =,当时太弱(其实现在也很弱),然后也是因为这道题来学习了一下状态压缩dp,其实也没学多少,因为状态压缩说实话范围挺广的...

Vijos P1002 过河

描述在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧。在桥上有一些石子,青蛙很讨厌踩在这些石子上。由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上的...

1010 过河卒

#include #include #include using namespace std; int xb,yb,hx,hy; int f[16][16]; bool cap[16][16]; ...
  • t_T_c
  • t_T_c
  • 2015-07-17 14:11
  • 138

Vijos P1002过河

描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧。在桥上有一些石子,青蛙很讨厌踩在这些石子上。由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)