📜  门| GATE-CS-2003 |问题11(1)

📅  最后修改于: 2023-12-03 15:28:41.869000             🧑  作者: Mango

门 | GATE-CS-2003 | 问题11

这是一道关于递归的问题,旨在帮助程序员了解递归函数的编写和应用。

问题描述

有一个围栏,由 n 个门构成,每个门可以是开的或者关的。门从第一个开始,编号为 1,到第 n 个门,编号为 n。现在,从第一个门开始,每次经过第 i 个门时,如果这扇门是开的,就进入第 i+1 个门,否则就进入第 i-1 个门。如果你走到门 n+1,就算你走到了终点。现在,问有多少种状态可以走到终点。

输入格式

输入的第一行包括一个整数,表示围栏的门数 n。接下来的一行包括 n 个整数,1 表示第 i 个门是开的,0 表示第 i 个门是关的。

输出格式

输出一个整数,表示有多少种状态可以走到终点。

解题思路

这道题可以使用递归方法解决。递归的方法是,从门 1 开始走,如果在走到门 n+1 之前,已经走了 n 个门,那么就说明走到了终点。

由于每走到一个门,都只有两种选择,即往前或往后走,所以有以下两种情况:

  1. 走到了门 i,这扇门是开的,接下来往门i+1走,即f(i+1);
  2. 走到了门i,这扇门是关的,接下来往门i-1走,即f(i-1)。

最后,将 f(1) 返回即可。

代码片段
/**
 * 输入一个长度为n的01序列,从第1个元素开始遍历,遇到1向前走,遇到0向后走,问能否遍历到n+1号元素
 * 递归函数
 * @param arr 01序列
 * @param n   序列长度
 * @param i   当前所在门的编号
 * @return    是否能到达n+1号门
 */
int canReach(int arr[], int n, int i)
{
    if (i < 1 || i > n)
    {
        // 走出了围栏,返回false
        return 0;
    }
    else if (i == n + 1)
    {
        // 走到了n+1号门,返回true
        return 1;
    }
    else if (arr[i - 1] == 1)
    {
        // 第i号门开着,往前走
        return canReach(arr, n, i + 1);
    }
    else if (arr[i - 1] == 0)
    {
        // 第i号门关着,往后走
        return canReach(arr, n, i - 1);
    }
}

/**
 * 题目11,门 | GATE-CS-2003 | 递归
 */
void question11()
{
    int n; // 门数
    cin >> n;

    int arr[n]; // 门的开关状态
    for (int i = 0; i < n; i++)
    {
        cin >> arr[i];
    }

    cout << canReach(arr, n, 1) << endl;
}