Skip to content

Latest commit

 

History

History
72 lines (60 loc) · 2.61 KB

1022. Digital Library.md

File metadata and controls

72 lines (60 loc) · 2.61 KB

【PAT A-1022】Digital Library

题意概述

给出一本书的 ID、标题、作者、关键词、出版社、出版年份。要求根据查询的信息给出符合要求的书籍 ID。

输入输出格式

第一行给出一个正整数 N,代表有 N 本书,然后紧跟着 6N 行,每 6 行按 ID、标题、作者、关键词、出版社、出版年份的顺序给出一本书籍信息。然后一行给出一个正整数 M,表示有 M 个查询。紧跟着 M 行,每行按a: 查询信息的格式查询信息,其中 a 是一个正整数,代表的意义如下:

  • a 为 1 表示按书籍标题查询;
  • a 为 2 表示按书籍作者查询;
  • a 为 3 表示按书籍关键词查询;
  • a 为 4 表示按书籍出版社查询;
  • a 为 5 表示按书籍出版年份查询。

先按a: 查询信息的格式输出查询信息,然后紧跟着输出所有符合查询条件的书籍 ID,每个 ID 占一行。如果没有符合查询条件的 ID,输出Not Found

数据规模

$$0<N \le {10}^4,0<M \le {10}^3$$

算法设计

针对不同的查询信息,都用一个unordered_map<string, set<string>>存储要查询的信息和对应的书籍 ID 的映射关系,其中 set 正好可以对 ID 进行排序。由于查询时是用一个正整数区分不同种类的查询方式,可以直接用vector<unordered_map<string, set<string>>>将不同种类的查询信息统一存储在一起,这样直接用查询的正整数作数组下标查询就非常方便了。

C++代码

#include <bits/stdc++.h>
using namespace std;
using gg = long long;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    gg ni, mi, ai;
    cin >> ni;
    cin.get();
    string id, si;
    vector<unordered_map<string, set<string>>> book(6);
    while (ni--) {
        getline(cin, id);
        for (gg i = 1; i <= 5; ++i) {
            getline(cin, si);
            if (i == 3) {  //对于keywords要按空格符分割
                stringstream ss(si);
                while (ss >> si) {
                    book[i][si].insert(id);
                }
            } else {
                book[i][si].insert(id);
            }
        }
    }
    cin >> mi;
    cin.get();
    while (mi--) {
        getline(cin, si);
        ai = stoll(si.substr(0, si.find(':')));  //分割出冒号前面的数字
        cout << si << "\n";
        si = si.substr(si.find(':') + 2);  //分割得到查询信息
        if (not book[ai].count(si)) {
            cout << "Not Found\n";
            continue;
        }
        for (auto& i : book[ai][si]) {
            cout << i << "\n";
        }
    }
    return 0;
}