[递归]排队游戏

例题(15.2)排队游戏

题目描述

在幼儿园中,老师安排小朋友做一个排队的游戏。首先老师精心的把数目相同的小男孩和小女孩编排在一个队列中,每个小孩按其在队列中的位置发给一个编号(编号从0开始)。然后老师告诉小朋友们,站在前边的小男孩可以和他后边相邻的小女孩手拉手离开队列,剩余的小朋友重新站拢,再按前后相邻的小男孩小女孩手拉手离开队列游戏,如此往复。由于教师精心的安排,恰好可以保证每两个小朋友都能手拉手离开队列,并且最后离开的两个小朋友是编号最小的和最大的两个小朋友。(注:只有小男孩在前,小女孩在后,且他们两之间没有其他的小朋友,他们才能手拉手离开队列)。请根据老师的排队,按小女孩编号从小到大的顺序,给出所有手拉手离开队列的小男孩和小女孩的编号对。

关于输入

用一个字符串代表小朋友队列。字符串中只会出现两个字符,分别代表小男孩和小女孩,首先出现的字符代表小男孩,另一个字符代表小女孩。小孩总数不超过100
注意:只会出现两个字符不代表只会出现括号()

关于输出

按小女孩编号顺序,顺序输出手拉手离开队列的小男孩和小女孩的编号对,每行一对编号,编号之间用一个空格分隔。

例子输入
((()(())())(()))
例子输出
2 3
5 6
4 7
8 9
1 10
12 13
11 14
0 15
解题分析

我们可以使用递归的方法来解决这个问题。主要的逻辑在于`findpair`函数,它接受一个字符串`s`(代表孩子们的队列),一个计数器`count`,一个字符`boy`(代表小男孩的字符),以及两个索引`start`和`end`(定义了我们正在查看的字符串的部分)。

在`findpair`函数中,首先检查是否满足递归的基本条件。如果`start`大于等于`end`,或者`end`小于0,或者`end`大于等于字符串的长度,或者`start`位置的字符不是小男孩,那么我们就返回,不再进行递归。

然后,我们开始遍历从`start+1`到`end`的字符串部分。我们遍历的同时维护一个计数器,如果遇到小男孩的字符,就增加计数器,如果遇到小女孩的字符,就减少计数器。当计数器变为0时,说明我们找到了一对小男孩和小女孩,他们可以手拉手离开队列。

在找到一对小男孩和小女孩后,我们首先递归地处理他们之前的字符串部分,然后打印出他们的编号,最后递归地处理他们之后的字符串部分。

在`main`函数中,我们首先读取队列字符串`s`,然后调用`findpair`函数开始处理。我们传递的初始参数是字符串`s`,计数器为1,小男孩的字符,以及字符串的开始和结束索引。

这个程序的主要原理是递归。它首先找到一对可以手拉手离开队列的小男孩和小女孩,然后递归地处理他们前后的字符串部分,直到处理完整个字符串。

代码实现
#include 
using namespace std;

void findpair(const string &s,int count,char boy,int start,int end){
    int i=start+1;
    if(start>=end || end<0 || end>=s.size() || s[start]!=boy) return;
    while(count && i<=end){
        if(s[i]==boy){
            count++;
        }
        else count--;
        i++;
    }
    findpair(s,1,boy,start+1,i-2);
    cout<

c语言版本

#include 
#include 

// 定义findpair函数,用于寻找可以手拉手离开队列的小男孩和小女孩
void findpair(const char *s, int count, char boy, int start, int end) {
    int i = start + 1;
    // 检查递归的基本条件,如果不满足则返回
    if (start >= end || end < 0 || end >= strlen(s) || s[start] != boy) return;
    // 遍历字符串,维护计数器,寻找可以手拉手离开队列的小男孩和小女孩
    while (count && i <= end) {
        if (s[i] == boy) {
            count++;
        } else count--;
        i++;
    }
    // 找到一对小男孩和小女孩后,递归处理他们之前的字符串部分
    findpair(s, 1, boy, start + 1, i - 2);
    // 打印小男孩和小女孩的编号
    printf("%d %d\n", start, i - 1);
    // 递归处理他们之后的字符串部分
    findpair(s, 1, boy, i, strlen(s) - 1);
}

int main() {
    char s[101]; // 假设字符串的最大长度为100
    fgets(s, 101, stdin); // 读取字符串
    s[strcspn(s, "\n")] = 0; // 删除换行符
    char boy = s[0]; // 获取小男孩的字符
    // 调用findpair函数开始处理
    findpair(s, 1, boy, 0, strlen(s) - 1);
    return 0;
}

你可能感兴趣的:(游戏)