• codevs 1010 过河卒


    题目描述 Description

     如图,A 点有一个过河卒,需要走到目标 B 点。卒行走规则:可以向下、或者向右。同时在棋盘上的任一点有一个对方的马(如上图的C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点。例如上图 C 点上的马可以控制 9 个点(图中的P1,P2 … P8 和 C)。卒不能通过对方马的控制点。


      棋盘用坐标表示,A 点(0,0)、B 点(n,m)(n,m 为不超过 20 的整数,并由键盘输入),同样马的位置坐标是需要给出的(约定: C不等于A,同时C不等于B)。现在要求你计算出卒从 A 点能够到达 B 点的路径的条数。

    1<=n,m<=15

    输入描述 Input Description

     键盘输入
       B点的坐标(n,m)以及对方马的坐标(X,Y){不用判错}

    输出描述 Output Description

      屏幕输出
        一个整数(路径的条数)。

    样例输入 Sample Input

     6 6 3 2

    样例输出 Sample Output

    17

    题目分析:

    要到达棋盘上的一个点,只能从左边过来(我们称之为左点)或是从上面过来(我们称之为上点),所以根据加法原理,到达某一点的路径数目,就等于到达其相邻的上点和左点的路径数目之和,因此我们可以使用逐列(或逐行)递推的方法来求出从起点到终点的路径数目。障碍点(马的控制点)也完全适用,只要将到达该点的路径数目设置为0即可。

    用F[i][j]表示到达点(i,j)的路径数目,g[i][j]表示点(i, j)有无障碍,g[i][j]=0表示无障碍,g[i][j]=1表示有障碍。
    则,递推关系式如下: F[i][j] = F[i-1][j] + F[i][j-1] //i>0且j>0且g[i][j]= 0
    递推边界有4个:
        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[0][0] = 1
    考虑到最大情况下:n=20,m=20,路径条数可能会超过231-1,所以要用高精度。

     1 #include <stdio.h>
     2 int main(int argc, char *argv[])
     3 {
     4     int F[21][21]={0},G[21][21]={0};
     5     int i,j;
     6     int n,m;//终点坐标
     7     int a,b;//马的坐标
     8     
     9     scanf("%d%d",&n,&m);//输入终点坐标 
    10     scanf("%d%d",&a,&b);//输入马的坐标    
    11     
    12     G[a][b]=1;
    13     if(a-2>=0&&b-1>=0)    {G[a-2][b-1]=1;}
    14     if(a-2>=0&&b+1<=m)    {G[a-2][b+1]=1;}
    15     if(a+2<=n&&b-1>=0)    {G[a+2][b-1]=1;}
    16     if(a+2<=n&&b+1<=m)    {G[a+2][b+1]=1;}
    17     
    18     if(a-1>=0&&b-2>=0)    {G[a-1][b-2]=1;}
    19     if(a-1>=0&&b+2<=m)    {G[a-1][b+2]=1;}
    20     if(a+1<=n&&b-2>=0)    {G[a+1][b-2]=1;}
    21     if(a+1<=n&&b+2<=m)    {G[a+1][b+2]=1;}
    22     
    23     for(i=0;i<=n;i++)//初始化第一行和第一列,均为1种走法。 
    24     {
    25         if(G[i][0]==0){F[i][0]=1;}
    26         else break;
    27     }
    28     for(i=0;i<=m;i++)
    29     {
    30         if(G[0][i]==0) {F[0][i]=1;}
    31         else break;
    32     }
    33     for(i=1;i<=m;i++)
    34     {
    35         for(j=1;j<=n;j++)
    36         {
    37             if(G[j][i]!=1)
    38             {
    39                 F[j][i]=F[j-1][i]+F[j][i-1];
    40             }
    41         }
    42     }
    43     printf("%d",F[n][m]);
    44     
    45     return 0;
    46 }

    另一段比较优秀的代码:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 int detX[8]={2,1,-1,-2,-2,-1,+1,+2};
     4 int detY[8]={1,2,+2,+1,-1,-2,-2,-1};
     5 int main()
     6 {
     7     int n,m,x,y,i,j;
     8     long long F[25][25]={0};
     9     int xx,yy;
    10     scanf("%d%d%d%d",&n,&m,&x,&y);
    11 
    12     F[x][y]=-1;
    13     for(i=0;i<8;i++)
    14     {
    15         xx=x+detX[i];  yy=y+detY[i];
    16         if(xx>=0&&xx<=n&&yy>=0&&yy<=m) F[xx][yy]=-1;
    17     }
    18 
    19     F[0][0]=1;
    20     for(i=1;i<=n;i++)//初始化第0列
    21     {
    22         if(F[i][0]!=-1) F[i][0]=F[i-1][0];
    23         else F[i][0]=0;
    24     }
    25     for(j=1;j<=m;j++)//初始化第0行
    26     {
    27         if(F[0][j]!=-1) F[0][j]=F[0][j-1];
    28         else F[0][j]=0;
    29     }
    30 
    31     for(i=1;i<=n;i++)
    32     {
    33         for(j=1;j<=m;j++)
    34         {
    35             if(F[i][j]!=-1) F[i][j]=F[i][j-1]+F[i-1][j];
    36             else F[i][j]=0;
    37         }
    38     }
    39     printf("%lld
    ",F[n][m]);
    40     return 0;
    41 }
  • 相关阅读:
    测试面试题集-接口测试(9)
    测试面试题集-性能测试(8)
    测试面试题集-网络基础(7)
    测试面试题集-Python编程题(6)
    测试面试题集-Python列表去重(5)
    测试面试题集-生活物品测试:杯子、伞、钢笔、桌子、行李箱、电梯、洗衣机(4)
    测试面试题集-测试用例设计(3)
    测试面试题集-测试基础理论(2)
    解决在docker环境中拉取svn项目中含有中文名称的文件时拉取失败的问题
    redisTemplate之opsForHash()用法分析
  • 原文地址:https://www.cnblogs.com/huashanqingzhu/p/10324414.html
Copyright © 2020-2023  润新知