• 【OJ题目】选择客栈 | 公司新表


    一、选择客栈

    1. 题目描述

    丽江河边有n家很有特色的客栈,客栈按照其位置顺序从1到n编号。每家客栈都按照某一种色调进行装饰(总共k种,用整数 0~k-1表示),且每家客栈都设有一家咖啡店,每家咖啡店均有各自的最低消费。

    两位游客一起去丽江旅游,他们喜欢相同的色调,又想尝试两个不同的客栈,因此决定分别住在色调相同的两家客栈中。晚上,他们打算选择一家咖啡店喝咖啡,要求咖啡店位于两人住的两家客栈之间(包括他们住的客栈),且咖啡店的最低消费不超过p。

    他们想知道总共有多少种选择住宿的方案,保证晚上可以找到一家最低消费不超过p元的咖啡店小聚。

    2. 输入描述:

    第一行三个整数 n,k,p,每两个整数之间用一个空格隔开,分别表示客栈的个数,色调的数目和能接受的最低消费的最高值;

    接下来的n行,第i+1行两个整数,之间用一个空格隔开,分别表示i号客栈的装饰色调和i号客栈的咖啡店的最低消费。

    3. 输出描述:

    输出只有一行,一个整数,表示可选的住宿方案的总数。

    4. 测试用例:

    5 2 3
    0 5
    1 3
    0 2
    1 4
    1 5

    5. 输出结果:

    3

    6. 解释:

    2人要住同样色调的客栈,所有可选的住宿方案包括:住客栈①③,②④,②⑤,④⑤,但是若选择住4、5号客栈的话,4、5号客栈之间的咖啡店的最低消费是4,而两人能承受的最低消费是3元,所以不满足要求。因此只有前3种方案可选。

    7.代码实现

    模拟过程并不好描述,博主也看了一些题解,都没有很好地讲清楚,所以将代码逐行注释,读者可以根据注释、代码进行理解,在此不再解释。

    int solution(int n, int k, int p, std::vector<std::vector<std::string>>& vec) {
        int result;
        // TODO:
        result = 0;
        vector<int> cur(k, 0);
        vector<int> sum(k, 0);
        for (int i = 0; i < n; i++) {
            int color = atoi(vec[i][0].c_str()); // 第i个客栈的颜色
            int price = atoi(vec[i][1].c_str()); // 第i个客栈的价格
            cur[color]++;                      // 当前段的颜色 ++
            if (price <= p) {                  // 证明找到了一个新的中间咖啡店
                for (int j = 0; j < k; j++) {  // 遍历所有颜色
                    sum[j] += cur[j];          // 之前的所有颜色可以累加到总数里了
                    cur[j] = 0;                // 当前颜色清零
                }
                result -= 1;        // 注意:因为2个人不能同时住在一个咖啡店,所以咖啡店不能包括当前这个,要-1
            }
            result += sum[color];   // 最终结果,每遍历一个客栈,相当于第二个人多了一种可能性,第一个人可以用之前的所有
        }
        return result;
    }
    
    int main() {
    
        int n;
        int k;
        int p;
        std::vector<std::vector<std::string>> vec;
    
        std::cin >> n;
        std::cin >> k;
        std::cin >> p;
    
        std::string line, token;
        for (size_t i = 0; i < n; i++) {
            std::vector<std::string> s;
    
            getline(std::cin >> std::ws, line);
            std::stringstream tokens(line);
            while (std::getline(tokens, token, ' ')) {
                s.push_back((token));
            }
    
            vec.push_back(s);
        }
    
    
        int result = solution(n, k, p, vec);
    
        std::cout << result << std::endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    二、公司新表

    1.题目描述

    公司里为了凸显公司的特性。安装了一个n进制表。

    已知新的表的时间是H:M。

    时间合法的定义为H<=23 && M<=59。

    时间有多少种进制定义的方式,依次打印出来。

    如果有无数种解输出-1,不存在输出0。

    2. 输入描述:

    输入一行字符串a:b形式。

    3. 输出描述:

    输出答案。

    4. 输入样例:

    11:20

    5. 输出样例:

    3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

    6. 代码实现

    最小的进制为2,最大的进制应该为59,因为分钟数不能超过60。据此进行枚举,如果最终列表为空,则返回0;如果60进制可用,则返回1。

    bool match(std::string str, int base) {
        int time[2] = { 0, 0 }, t = 0;              // 定义小时和分钟数组 及 索引
        for (int i = 0; i < str.length(); i++) {    // 遍历字符串
            if (str[i] == ':') {                    // 如果遇到 : 证明该切换到下一组了
                t = 1;
                continue;
            }
            int x = (str[i] >= '0' && str[i] <= '9') ? (str[i] - '0') : (str[i] - 'A' + 10); // 将 char 类型转为 int
            if (x < base)                    // 如果当前值没超过进制范围,进行累加求和
                time[t] = time[t] * base + x; 
            else                             // 如果当前值已经超过了进制的范围,直接返回 false
                return false;
        }
        return time[0] < 24 && time[1] < 60; // 判断两个数字(小时和分钟)是否满足范围
    }
    
    std::vector<int> solution(std::string m) {
        std::vector<int> result;
        // TODO:
        for (int i = 2; i < 60; i++) { // 枚举 2~59 进制,并判断是否超范围
            if (match(m, i)) result.push_back(i);
        }
        if (result.empty()) {          // 如果全部不可用,返回 0
            result.push_back(0);
            return result;
        }
        if (match(m, 60)) {    // 如果 60 进制都可以用,证明有无数种可能,返回 -1
            result.clear();
            result.push_back(-1);
            return result;
        }
        return result;
    }
    
    int main() {
    
        std::string m;
    
        getline(std::cin, m);;
    
        std::vector<int> result = solution(m);
    
    
        for (auto it = result.begin(); it != result.end(); ++it) {
            std::cout << *it << " ";
        }
        std::cout << std::endl;
    
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
  • 相关阅读:
    你有对象类,我有结构体,Go lang1.18入门精炼教程,由白丁入鸿儒,go lang结构体(struct)的使用EP06
    【vscode】Window11环境下vscode使用Fira Code字体【教程】
    【目标检测】40、DenseNet | 通过密集连接让信息实现层间最大流动的主干网络
    锐捷BFD基础实验配置
    春雷在线考试系统
    DeepMind 的新强化学习系统是迈向通用 AI 的一步吗?
    这个项目,荣获“绽放杯”一等奖!
    Verilog 的层次化事件队列+阻塞赋值与非阻塞赋值理解
    5. RxJava合并条件操作符
    10_ue4进阶_添加倒地和施法动作
  • 原文地址:https://blog.csdn.net/myf_666/article/details/129328041