【东华大学oj】牧场安全系统(字符串->较难)

牧场安全系统

时间限制: 10S类别: 字符串->较难

问题描述 :

明明是一家养牛场的老板,随着养牛场的规模扩大,牛的数量变得越来越多。因此,管理也就越来越难,还时常发生一些事故,比如:一些牛会走失,一些牛会因为疏忽照顾而生长不佳等等,这些都给明明造成了损失。于是,明明决定给养牛场安装一套现代化的生产管理系统,用科学的方法来管理养牛场,在这套安全系统中,需要为每头牛编一个号码,这个号码是唯一的,用来标识每一头牛。这样明明在管理时,就不会疏忽任意一头牛,也不会使牛再次走失。但是在给每头牛编号的时候,明明遇到了困难,由于系统的原因,系统对每头牛的编号有一定的限制,这个编号必须有L个小写字母组成,这些小写字母必须在固定的几个字母中选择,并且在这个编号中至少要有一个元音('a', 'e', 'i', 'o', 或者 'u'),至少有两个辅音(除去元音以外的音节), 并且字母按字母表顺序排列(例如,'abc'是有效的,而'bac'不是有效的)。 例如:假设编号由5个小写字母组成,且这些小写字母只能为a、b、c、d、e、f,这样构成的可能的编号就有以下6种: bcdef acdef abdef abcef abcdf abcde 明明觉得这样编号的方法非常麻烦,仅仅靠手工排列是很难完成的,出错的可能性很大,这时,明明想起了你,你是一位程序设计专家,你能否帮明明写一个程序,帮助他按照编号的规则,由程序生成所有的有效编号,供明明使用。 明明的问题可以归结为:给你一个有效编号的长度L,和C个可用的小写字母,按照编码规则生成所有的有效编号。

输入说明 :

你写的程序要求从标准输入设备中读入测试数据作为你所写程序的输入数据。标准输入设备中有多组测试数据,每组测试数据有二行,第一行为两个整数L(3≤L≤15)和C(3≤C≤26),L表示编号的长度,C表示可以选择的小写字母的数量,L和C用一个空格隔开。第二行有C个两两不相同的小写字母,相互以一个空格隔开。每组测试数据与其后一组测试数据之间没有任何空行,第一组测试数据前面以及最后一组测试数据后面也都没有任何空行。

输出说明 :

对于每一组测试数据,你写的程序要求计算出一组相应的运算结果,并将这一组运算结果作为你所写程序的输出数据依次写入到标准输出设备中。每组运算结果分为两个部分,第一部分为所有生成的有效编号,每行一个,按字母表逆序顺序输出,第二部分为一个整数,表示总共有多少个有效编码。 每组运算结果的行首和行尾都没有任何空格,每组运算结果与其后一组运算结果之间有一个空行,最后一组运算结果后面没有空行。 注:通常,显示屏为标准输出设备。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//vowel元音 consonant 辅音
//递归函数,注意一定要传递引用!(前车之鉴,找了半天的低级错误...)
void generateCodes(int l, vector<char>& letters, string code, int vowels, int consonants, int last, vector<string>& codes)
{
    if (code.length() == l)
    {
        if (vowels >= 1 && consonants >= 2)
        {
            codes.push_back(code);
        }
        return;
    }

    for (int i = last + 1; i < letters.size(); ++i)
    {
        int new_vowels = vowels;
        int new_consonants = consonants;

        //确认当前的字母是元音还是辅音
        if (letters[i] == 'a' || letters[i] == 'e' || letters[i] == 'i' || letters[i] == 'o' || letters[i] == 'u')
        {
            new_vowels++;
        }
        else
        {
            new_consonants++;
        }

        generateCodes(l, letters, code + letters[i], new_vowels, new_consonants, i, codes);
    }
}

int main()
{
    int L, C;
    while (cin >> L >> C)
    {
        vector<char> letters(C);
        for (int i = 0; i < C; ++i)
        {
            cin >> letters[i];
        }

        //按照字典序列排序
        sort(letters.begin(), letters.end());

        vector<string> codes;
        generateCodes(L, letters, "", 0, 0, -1, codes);

        //输出的时候反字典序
        sort(codes.rbegin(), codes.rend());

        //输出
        for (const string& code : codes)
        {
            cout << code << endl;
        }

        // 输出有效的字符串个数
        cout << codes.size() << endl;

        //换行
        if (cin.peek() != EOF) cout << endl;
    }

    return 0;
}

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ixll625

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值