ACM 排队买票

探讨了M个小孩排队买票的排列问题,其中N个小孩带1元,K个小孩带2元,售票员无零钱。通过递归算法计算所有可能的排队方案,确保售票员总能找到零钱。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题 1163: 【排队买票】

问题描述
有M个小孩到公园玩,门票是1元。其中N个小孩带的钱为1元,K个小孩带的钱为2元。售票员没有零钱,问这些小孩共有多少种排队方法,使得售票员总能找得开零钱。注意:两个拿一元零钱的小孩,他们的位置互换,也算是一种新的排法。(M<=10)
输入

输入一行,M,N,K(其中M=N+K,M<=10).
输出

输出一行,总的排队方案。
样例输入

4 2 2

样例输出

8

递归解决排列问题
先算出不交换相同零钱小孩时的情况数
再乘两个小孩数的阶乘

long int qk(int lq, int a1,int a2)
{
    if(lq<0 ||(a1==0&&a2>lq))		//当在这个情况下无法满足条件
        return 0;
    if(a1==0||a2==0)					//在除去上面情况外,这个情况满足条件,总数加一
        return 1;
    if(lq==0)							//零钱为零只能存在下一个小孩拿一块的情况
        return qk(lq+1,a1-1,a2);
    return (qk(lq+1,a1-1,a2)+qk(lq-1,a1,a2-1));		//如果上面都不符合,即可以出现两种情况
}

参考代码

#include <iostream>

#include <stdio.h>

using namespace std;
long int qk(int lq,int a1,int a2);
long int jc(int n);

int main()
{
    int m,a1,a2;
    while(scanf("%d %d %d",&m,&a1,&a2)!=EOF)
    {
        long int s=0;
        if(a1<a2)
            cout << "0"<<endl;
        else
        {
            s=qk(1,a1-1,a2);
            s=jc(a1)*jc(a2)*s;
            cout <<s<<endl;
        }
    }

    return 0;
}

long int qk(int lq, int a1,int a2)
{
    if(lq<0 ||(a1==0&&a2>lq))
        return 0;
    if(a1==0||a2==0)
        return 1;
    if(lq==0)
        return qk(lq+1,a1-1,a2);
    return (qk(lq+1,a1-1,a2)+qk(lq-1,a1,a2-1));
}
long int jc(int n)
{
    int s=1;
    for(int i=n;i>1;i--)
    {
        s*=i;
    }
    return s;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值