• 第四届蓝桥杯C/C++A组题目:振兴中华


      首先把题目贴上来吧!

      小明参加了学校的趣味运动会,其中的一个项目是:跳格子。

      地上画着一些格子,每个格子里写一个字,如下所示:(也可参见图1)

        从我做起振
        我做起振兴
        做起振兴中
        起振兴中华

      图1

      比赛时,先站在左上角的写着“从”字的格子里,可以横向或纵向跳到相邻的格子里,但不能跳到对角的格子或其它位置。一直要跳到“华”字结束。

      要求跳过的路线刚好构成“从我做起振兴中华”这句话。

      请你帮助小明算一算他一共有多少种可能的跳跃路线呢?

      这个题目蛮简单,所以为了提升难度,后来我又添加了两个要求:

      1.能够把所有行走的路径输出出来!

      2.能够按照要求输出特定一条路径。(比如这条路径: 从→我↓做↓起↓振→兴→中→华)

      OK,简单说一下我的思路:

        首先把“从我做起,振兴中华”这八个字按照0~7的顺序编好,然后把这个方格存放在一个4*5的二维数组array里面,同时,设定一个同样大小的flag数组来存放行走轨迹,最后还要设定一个road_flag[7]的数组来记录行走的步子是横向还是纵向。

        

        接下来就是利用递归遍历这个二维数组,

        递归过程是:从0,0开始,横着或者竖着前进,向前前进一格的条件就是没有超出范围,并且下一格的数字比这一格大1。每次前进一格后,就把flag数组中相应的位置标记为1,同时根据行走的步子的方向来对road_flag中的相应步数进行标记。

        如果到达了华这个字(相应的数字为7),那么就到了递归出口,判断这一条路径是否符合要求,是否能够输出,然后返回。

        函数返回之后,要把相应的路径标记和步子标记清除。

        就这样一直遍历,直到把所有的路径都找出来!

      程序的代码如下:

     1 #include<stdio.h>
     2 #include<string.h>
     3 #define ROW 4
     4 #define COL 5
     5 
     6 int count;        //统计路径的次数
     7 int flag[ROW][COL]; //路径标记
     8 int road_flag[ROW+COL-1];   //步子标记
     9 int road_count;        //用来记录走的步数
    10 
    11 int road(int arr[][COL],int row,int col);
    12 
    13 int main(int argc,char *argv[])
    14 {
    15     int array[ROW][COL] = {
    16     {0,1,2,3,4},
    17     {1,2,3,4,5},
    18     {2,3,4,5,6},
    19     {3,4,5,6,7}   };
    20 
    21     road(array,0,0);
    22     printf("count = %d
    ",count);
    23 
    24     return 0;
    25 }
    26 int road(int arr[][COL],int row,int col)
    27 {
    28     flag[row][col]=1;    //标记路径
    29 
    30     if(arr[row][col] == 7)
    31     {
    32     count++;
    33     //printf("No.%d:
    ",count);
    34 
    35     //判断这一条路径是否符合我们的要求
    36     if(1==road_flag[0] && 2==road_flag[1] && 2==road_flag[2] &&
    37        2==road_flag[3] && 1==road_flag[4] && 1==road_flag[5] &&
    38        1==road_flag[6]
    39     )
    40         for(int rloop=0;rloop<ROW;rloop++)
    41         {
    42         for(int cloop=0;cloop<COL;cloop++)
    43         if(1 == flag[rloop][cloop])
    44             printf(" # ");
    45         else
    46             printf(" ^ ");
    47         printf("
    ");
    48         }
    49     return 0;
    50     }
    51     //横向走
    52     if(col+1<COL && arr[row][col+1]==arr[row][col]+1)
    53     {
    54     road_flag[road_count] = 1;  //标记步子
    55     road_count++;
    56 
    57     road(arr,row,col+1);    
    58 
    59     //取消路径和步子标记
    60     flag[row][col+1] = 0;
    61     road_count--;
    62     road_flag[road_count] = 0;
    63     }
    64     //纵向走
    65     if(row+1<ROW && arr[row+1][col]==arr[row][col]+1)
    66     {
    67     road_flag[road_count] = 2;  //标记步子
    68     road_count++;
    69 
    70     road(arr,row+1,col);
    71 
    72     //取消路径和步子标记
    73     flag[row+1][col] = 0;
    74     road_count--;
    75     road_flag[road_count] = 0;
    76     }
    77 }

      Ok,上面这个程序就能够按照我们的要求输出特定的路径(从→我↓做↓起↓振→兴→中→华),而那个count就是一共有多少条路径!如果想要输出全部的路径,只需要把递归出口中的那个if语句(36~39)去掉,并且把它上面的那个printf语句的注释(33)取消掉,就能查看所有的路径了!

      程序的运行结果如下:

      

      输出全部路径的结果则如下图:

      

      Ok,That‘s all!希望能够对大家有帮助!

  • 相关阅读:
    网络流24题总结和题解
    NOIP复习之1 数学数论
    BZOJ3301 P2524 UVA11525 算法解释康托展开
    线段树与树状数组的综合运用
    P2261 bzoj1257 [CQOI2007]余数求和
    BZOJ 1968_P1403 [AHOI2005]约数研究--p2260bzoj2956-模积和∑----信息学中的数论分块
    P1064 金明的预算方案
    洛谷p1002 过河卒
    Luogu P3014 [USACO11FEB]牛线Cow Line
    Luogu P3927 SAC E#1
  • 原文地址:https://www.cnblogs.com/bwangel23/p/4278629.html
Copyright © 2020-2023  润新知