信息学奥赛一本通题目解析:1415:【17NOIP普及组】图书管理员(字符串)

【题目描述】

图书馆中每本书都有一个图书编码,可以用于快速检索图书,这个图书编码是一个 正整数。 每位借书的读者手中有一个需求码,这个需求码也是一个正整数。如果一本书的图 书编码恰好以读者的需求码结尾,那么这本书就是这位读者所需要的。 小 D 刚刚当上图书馆的管理员,她知道图书馆里所有书的图书编码,她请你帮她写 一个程序,对于每一位读者,求出他所需要的书中图书编码最小的那本书,如果没有他 需要的书,请输出-1。

【输入】

第一行,包含两个正整数 n 和 q,以一个空格分开,分别代表图书馆里 书的数量和读者的数量。  接下来的 n 行,每行包含一个正整数,代表图书馆里某本书的图书编码。  接下来的 q 行,每行包含两个正整数,以一个空格分开,第一个正整数代表图书馆 里读者的需求码的长度,第二个正整数代表读者的需求码。

【输出】

件有 q 行,每行包含一个整数,如果存在第 i 个读者所需要的书,则在第 i 行输出第 i 个读者所需要的书中图书编码最小的那本书的图书编码,否则输出-1。

【输入样例】

5 5
2123
1123
23
24
24
2 23
3 123
3 124
2 12
2 12

【输出样例】

23
1123
-1
-1
-1

【提示】

第一位读者需要的书有 2123、1123、23,其中 23 是最小的图书编码。第二位读者需要 的书有 2123、1123,其中 1123 是最小的图书编码。对于第三位,第四位和第五位读者,没 有书的图书编码以他们的需求码结尾,即没有他们需要的书,输出-1。

【数据规模与约定】

对于 20%的数据,1 ≤ n ≤ 2。

另有 20%的数据,q = 1。

另有 20%的数据,所有读者的需求码的长度均为 1。

另有 20%的数据,所有的图书编码按从小到大的顺序给出。

对于 100%的数据,1 ≤ n ≤ 1,000,1 ≤ q ≤ 1,000,所有的图书编码和需求码均 不超过 10,000,000。

【样例分析】

输入样例

5 5

2123

1123

23

24

24

2 23

3 123

3 124

2 12

2 12

  • 这里有5本书,它们的图书编码分别是21231123232424
  • 有5位读者,每位读者的需求码长度和需求码分别是:
    • 长度为2,需求码为23
    • 长度为3,需求码为123
    • 长度为3,需求码为124
    • 长度为2,需求码为12
    • 长度为2,需求码为12(重复)

处理过程

  1. 排序:根据编码长度和字典序排序后,图书编码顺序为23242411232123
  2. 第一位读者:需求码为23,匹配的图书编码是23(最小的匹配项)。
  3. 第二位读者:需求码为123,匹配的图书编码是1123(最小的匹配项)。
  4. 第三位读者:需求码为124,没有匹配的图书编码,输出-1
  5. 第四位读者:需求码为12,没有以12结尾的图书编码,输出-1
  6. 第五位读者:需求码再次为12,情况同第四位读者,输出-1

输出样例

23 1123 -1 -1 -1

直观分析

  • 第一位读者找到了以23结尾的最小图书编码23
  • 第二位读者找到了以123结尾的最小图书编码1123
  • 第三位读者没有找到以124结尾的图书编码。
  • 第四位和第五位读者由于没有书的编码以12结尾,所以也没有找到匹配的图书编码。

这个例子展示了程序如何根据每位读者的需求码查找和确定图书馆中编码以特定数字结尾的最小图书编码,如果不存在这样的图书编码,则输出-1

【解题思路】

  1. 字符串存储和比较:首先,将所有图书编码作为字符串读入并存储。这样做的好处是直接利用字符串来进行末尾匹配检查,避免了将图书编码从整数转换为字符串的步骤。

  2. 自定义排序:使用自定义的比较函数string_comp对图书编码进行排序。这个比较函数首先根据字符串的长度进行排序,如果长度相同,则根据字典顺序排序。这样确保了在遍历图书编码时,可以更快地找到匹配的最小编码,因为短的编码数值小,且排序后更容易匹配。

  3. 处理每个读者的需求:对于每位读者,读入需求码的长度和需求码本身。需求码的长度这里实际上是用不到的,因为是直接通过字符串进行末尾匹配的判断。

  4. 匹配和输出:通过遍历所有图书编码,并使用字符串的substr方法检查每个图书编码是否以需求码结尾。一旦找到第一个这样的图书编码,就输出该编码并停止搜索。如果没有找到任何匹配的图书编码,则输出-1。

  5. 优化:通过排序和直接以字符串形式处理编码,避免了不必要的数据类型转换,并简化了匹配逻辑。

【代码实现】

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;

string book[1001]; // 存储图书编码的数组

// 自定义比较函数,先按长度排序,长度相同则按字典序排序
bool string_comp(string a, string b) {
    if (a.size() != b.size()) {
        return a.size() < b.size();
    }
    return a < b;
}

int main() {
    int n, q;
    cin >> n >> q; // 读入图书数量和读者数量
    for (int i = 0; i < n; i++) {
        cin >> book[i]; // 读入图书编码
    }
    // 根据自定义的比较函数对图书编码进行排序
    sort(book, book + n, string_comp);
    
    for (int i = 0; i < q; i++) {
        int len; // 读者需求码的长度,虽读入但未使用
        string num; // 读者的需求码
        cin >> len >> num;
        bool f = false; // 标记是否找到匹配的图书编码
        for (int j = 0; j < n; j++) {
            // 如果当前图书编码的长度小于需求码的长度,则跳过
            if (book[j].size() < len) {
                continue;
            } else {
                // 使用substr方法检查图书编码是否以需求码结尾
                if (book[j].substr(book[j].size() - len, len) == num) {
                    cout << book[j] << endl; // 输出匹配的图书编码
                    f = true; // 标记已找到
                    break; // 找到后即停止搜索
                }
            }
        }
        if (!f) { // 如果没有找到匹配的图书编码
            cout << -1 << endl; // 输出-1
        }
    }
    return 0;
}

  • 22
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
信息学奥赛一本通 NOIP500 第1部分》是一本参考书籍,其主要目的是为了帮助准备参加NOIP(全国青少年信息学奥林匹克的省级选拔赛)的学生进行备考。这本书的内容丰富多样,涵盖了计算机科学和编程的各个方面。 在这本书的第1部分,主要介绍了NOIP500比赛的背景和要求。它首先详细解释了NOIP500的含义和意义,以及为什么要参加这样的比赛。它还介绍了NOIP500的考试形式和内容,包括必考的算法、数据结构和编程语言等。此外,它还介绍了评分标准和考试日期等重要信息。 第1部分还包括了一些备考的重要指导和技巧。它解释了如何正确准备和安排备考时间,以及如何理解和解答常见的考试题型。此外,书中还提供了一些实用的练习题和例子,帮助学生加深对知识点的理解和掌握。 这本书的语言简洁明了,结构清晰,非常适合初学者使用。它通过大量的例子和习题,帮助学生从基础知识开始逐步提高。此外,书中还附有一些重要的参考资料和学习资源,让学生能够更加全面地了解和学习计算机科学和编程。 总体而言,《信息学奥赛一本通 NOIP500 第1部分》是一本非常有价值的参考书籍,它能够为准备参加NOIP500的学生提供全面和系统的知识,帮助他们在竞赛中取得良好的成绩。对于对信息学感兴趣的学生,这本书也是一本很好的自学教材。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值