首页 > 试题广场 >

阅读理解

[编程题]阅读理解
  • 热度指数:1156 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
\hspace{15pt} 英语老师布置了 N 篇阅读理解作业。对于若干给定的生词,老师想知道它们分别出现在了哪些短文中,以便统计查词量。

\hspace{15pt} 给定 N 篇短文与 M 次查询,每次给出一个单词 w,请输出 w 出现过的所有短文编号(按升序),若从未出现则输出空行。

输入描述:
\hspace{15pt} 第一行输入整数 N\ (1\leqq N\leqq 10^{3})

\hspace{15pt} 接下来 N 行描述各短文,其中的第 i 行先给出整数 L_i(1\leqq L_i\leqq50)——该短文包含的单词数量 ,随后 L_i 个仅由小写英文字母组成的单词,每个单词长度不超过 20 个字符,单词之间以单个空格分隔。

\hspace{15pt} 紧接着输入整数 M\ (1\leqq M\leqq 10^{4})——查询次数。

\hspace{15pt} 之后 M 行,每行一个小写单词 w_j,表示一次查询。


输出描述:
\hspace{15pt} 对于每个查询单词 w_j
{\hspace{23pt}}\bullet\,w_j 出现过,输出其出现过的短文编号(1\sim N),按升序用单个空格分隔;
{\hspace{23pt}}\bullet\, 若未出现,输出空行。

\hspace{15pt} 输出中每个查询对应一行,行首行尾均无多余空格。
示例1

输入

3
9 you are a good boy ha ha o yeah
13 o my god you like bleach naruto one piece and so do i
11 but i do not think you will get all the points
5
you
i
o
all
naruto

输出

1 2 3
2 3
1 2
3
2

备注:

今天是哈希表模板题喵~
猫猫会帮你的!

对于这道题,猫猫第一想法是创建一个map < string , set <int> > 作为哈希表喵!猫猫把它称为index
猫猫来解释这个结构喵:它的键是string类型(单词),值是set<int>类型(包含该单词的短文编号集合)。
因为set能自动去重和排序喵!
循环中读取每篇短文的单词,并用index[word].insert(i)将短文编号i添加到单词word对应的集合中。这样index就记录了每个单词出现在哪些短文里喵!
最后直接输出需要查询的单词里的set<int>并输出就可以了喵!
今天的题好简单喵!(ฅ´ωฅ)可以给猫猫吃小鱼喵!
#include <bits/stdc++.h>
using namespace std;
using ll=long long;

int main() {
    cin.tie(0)->sync_with_stdio(0);

    int N;cin >> N;
    
    map<string, set<int>> index;//构建哈希表(set为了去重)
    
    for (int i = 1; i <= N; i++) 
    {
        int L;cin >> L;//单词数量
        for (int j = 0; j < L; j++) 
        {
            string word;
            cin >> word;
            index[word].insert(i);
        }
    }
    
    int M;cin >> M;
    
    for (int j = 0; j < M; j++) {
        string w;
        cin >> w;
        for(int i:index[w])cout << i <<' ';
        cout << '\n';
    }
    
    return 0;
}
/*
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⣤⡀⣀⣠⣤⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⡀⢀⣴⣾⣷⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣷⣾⣿⣷⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⠿⠛⠛⠉⠉⠉⠉⠉⠉⠛⠻⠿⣿⣿⣿⣿⣿⣶⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⢠⣾⣿⣿⣿⡿⠿⠛⠉⠉⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠿⣿⣿⣿⣷⣄⡀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⣀⣿⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⣰⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠿⣿⣿⣿⡄⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⣠⣾⣿⣿⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣶⣄⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣻⣿⣿⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⢹⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⠁⠈⢢⡀⠀⠀⠀⢸⡇⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⣿⡟⠒⢦⡀⠀⠀⠀
⠀⠀⣠⣤⣤⣼⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⡇⠀⠀⠀⠉⢢⣄⠀⠀⢿⠊⠳⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣷⡄⠀⢷⠀⠀⠀
⠀⢰⠇⠀⣰⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⡌⣹⠗⠦⣬⣇⠀⠉⢢⡀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⡀⢸⡄⠀⠀
⠀⡟⠀⣼⣯⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣆⢹⡀⠀⠀⠀⠉⠁⠀⠀⢀⣀⡁⠀⠀⠉⠳⢴⡆⠀⠀⠀⠀⠀⠀⢹⣧⠈⡇⠀⠀
⠀⡇⠀⠀⢻⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣾⠻⠉⠛⠂⠀⠀⠀⠀⠀⠀⠻⠿⣿⣿⣿⣶⣦⡀⠛⣇⠀⠀⠀⠀⠀⣈⣿⠀⡇⠀⠀
⢸⡇⠀⠀⢠⣿⣷⣦⣀⡸⣷⣦⣶⡂⠉⠉⠉⢁⣤⣶⡶⠀⠀⠀⣀⣀⡴⠀⠀⠀⠀⠀⠀⠈⠉⠉⠁⠀⡟⢀⣴⣟⣰⣾⣿⣏⣠⠇⠀⠀
⠈⡇⠀⠀⢸⣿⠁⠉⣿⠛⠛⠃⡇⠀⠀⢠⣶⣿⡿⠛⠁⠀⠀⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠼⢿⠟⠿⢿⡏⠀⠘⣿⡀⠀⠀⠀
⠀⢷⣀⣀⣿⠇⠀⠀⢿⡇⠀⢀⢱⡀⠀⠛⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⠀⠀⢸⠇⠀⠀⢹⣿⣄⠀⠀
⠀⠀⣉⣿⡏⠀⠀⠀⠀⠀⠀⢸⣇⣳⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡰⣿⠃⠀⠀⠀⠀⠀⠀⣿⠈⢧⠀
⠀⠘⣿⣿⠁⠀⠀⠀⠀⠀⠀⠘⣿⡛⣶⠀⠀⣠⠔⠒⠛⠒⠦⡀⠀⠀⠀⠀⣠⡤⠶⠤⢤⣀⠀⠀⠀⢀⣏⡄⠀⠀⠀⠀⠀⡀⣿⡆⠈⣧
⣠⡾⠛⣿⣿⣧⠀⠀⠀⠀⢸⣿⠾⢿⡿⠀⣰⠃⠀⠀⠀⠀⠀⢹⡄⠀⠀⡼⠁⠀⠀⠀⠀⠈⠙⣦⠀⢸⣿⡇⣾⣣⡀⠀⢰⣿⣿⣿⣤⠾
⡟⠀⠀⠻⣿⡟⢷⡄⣤⡀⠈⣿⡀⣸⠇⠀⠏⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⡇⢀⡀⠀⠀⠀⠀⢀⡟⠀⠀⠋⣿⣿⣿⡇⣠⣿⠿⠛⢷⡀⠀
⠀⠀⠀⠀⣿⣇⣨⣿⣿⣿⣦⣽⣷⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⠀⠃⠀⠙⠢⠤⠤⠴⢾⠀⠀⠀⠀⢸⣷⣿⣿⠟⠁⠀⠀⠈⣧⠀
⠀⠀⠀⠀⠈⠉⠉⠁⠈⠉⠈⢉⣿⡁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⢸⡇⠀⠀⠀⠀⠀⠀⠀⣿⠀
*/


发表于 2026-01-19 00:28:40 回复(0)

噗嗤——这种连幼稚园小朋友都能秒杀的题目,居然还有人需要看题解?真是逊毙了!你们这群杂鱼平时写代码难道都不动脑子的吗?
详情可看**************************
既然你们求而不得,本天才少女加藤翔子就大发慈悲地给你们写一篇吧。好好盯着看,这可是为了救赎你们那可怜的智商才写的!


📚 杂鱼也能懂的题解:英语老师的阅读理解

🧐 核心槽点:题面是用来骗笨蛋的!

听好了,笨蛋杂鱼们!这道题最坑的地方就在于——题面说单词只由“小写英文字母”组成,但实际的数据里可能藏着各种奇怪的非字母字符。

如果你在处理字符串时想当然地去过滤或者只考虑小写字母,你就等着吃红色的 WA 吧!这种基础中的基础,只有没用的杂鱼才会中招呢,呵呵~

💡 翔子的天才思路

这种题目的本质就是建立一个倒排索引(Inverted Index)

  1. 数据结构:用一个映射表(C++ 里的 map 或 Python 里的 dict)。键(Key)是单词字符串,值(Value)是一个存储短文编号的动态数组(vectorlist)。
  2. 去重处理:同一篇短文里某个单词可能出现好几次。为了不输出重复的编号,每次往数组里加编号前,先看看最后加进去的是不是当前这篇。如果已经加过了,就别再加了,这种逻辑对杂鱼来说应该不难理解吧?
  3. 读入技巧
  • 直接把单词当成字符串读进去就行了。
  • 千万不要管它里面有什么字符,原封不动地存起来就是唯一的标准!

💻 毫无难度的 C++ 代码

这种 的复杂度,简直是在浪费本天才的 CPU 时间。

#include <bits/stdc++.h>
using namespace std;

// 只有杂鱼才会写出一堆没用的宏定义...
void solve() {
    int n;
    cin>>n;
    map<string ,vector<int>>mp;
    for(int i=1;i<=n;i++){
        int m;
        cin>>m;
        for(int j=1;j<=m;j++){
            string s;
            cin>>s;
            if(mp.count(s)){
                if(mp[s].back()!=i){
                    mp[s].push_back(i);
                }
            }else{
                mp[s].push_back(i);
            }
        }
    }

    int q;
    cin>>q;
    while(q--){
        string s;
        cin>>s;
        for(auto id:mp[s]){
            cout<<id<<" ";
        }
        cout<<'\n';// 即使没出现也要输出空行,这都不懂可以回炉重造了
    }
}

int main(){
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);

    int t = 1;

    // cin >> t;

    while (t--){

        solve();
    }

    return 0;
}



🐍 连笨蛋都能跑通的 Python 代码

Python 的处理速度虽然像杂鱼一样慢,但在写起来确实省事呢。

import sys
import math
import queue
import itertools
import heapq
from collections import deque
from array import array
from bisect import bisect_right

# from dataclasses import dataclass
sys.setrecursionlimit(1145141919)
input = sys.stdin.readline


def read():
    line = sys.stdin.readline()
    if not line:
        return []
    return list(map(int, line.split()))


def readf():
    line = sys.stdin.readline()
    if not line:
        return []
    return list(map(float, line.split()))


mod = 10**9 + 7
inf = 10**18
MOD = 998244353
N = 2 * (10**5) + 5

def solve():
    n = read()[0]
    mp = {}
    for i in range(n):
        a = sys.stdin.readline().split()
        m = int(a[0])
        for j in range(1, m + 1):
            if a[j] not in mp:
                mp[a[j]] = [i + 1]
            else:
                if mp[a[j]][-1] != i + 1:
                    mp[a[j]].append(i + 1)

    q = read()[0]
    for i in range(q):
        s = input().strip()
        if s in mp:
            print(' '.join(map(str, mp[s])))
        else:
            print()# 找不到就输出空行,杂鱼听懂了吗?


def main():
    t = 1
    # t = int(sys.stdin.readline())
    for _ in range(t):
        solve()


if __name__ == "__main__":
    main()


🙄 翔子的最后叮嘱

看完了吗?看完了就赶紧滚去提交!

记得,不要去过滤任何字符!题面说是小写字母,你就真信啊?那只是为了糊弄你们这些不带脑子写代码的弱小杂鱼。数据里混进什么奇怪的东西,只要你用 string 原样存进去,查询的时候自然能对上。

要是连这都过不了,我就要考虑在你的代码库里投毒了哟~ 呵呵。


这种程度的题,下次别再拿来浪费我的时间了,知道了吗?

编辑于 2026-01-19 12:50:24 回复(0)
可以改一下题面中的(仅由小写英文字母组成)这句话吧,事实上样例里大小写字母和其他字符都有,我用tire写的老是段错误
简单介绍一下trie,trie树每个结点代表从根节点到当前节点,通过的代表字符的边按顺序组成的字符串
所以可以在每个结点维护一个数据结构来存当前节点代表的字符串,出现在的文章的索引;
注意一个文章可能会出现多个相同单词,所以用set存
代码如下
#pragma GCC optimize("O3", "inline", "omit-frame-pointer", "unroll-loops", "fast-math")
#include <bits/stdc++.h>
using namespace std;
struct node
{
    map<char, int> tr;
    set<int> idx;
} tire[100005];
int cnt = 0;
void upd(string s, int x)
{
    int p = 0;
    for (char c : s)
    {

        if (tire[p].tr[c] == 0)
        {
            tire[p].tr[c] = ++cnt;
            p = cnt;
        }
        else
        {
            p = tire[p].tr[c];
        }
    }
    tire[p].idx.insert(x);
}
void calc(string s)
{
    int p = 0;
    for (char c : s)
    {
        if (tire[p].tr[c] == 0)
        {
            cout << '\n';
            return;
        }
        else
        {
            p = tire[p].tr[c];
        }
    }
    for (int y : tire[p].idx)
    {
        cout << y << ' ';
    }
    cout << '\n';
}

void solve()
{
    int N;
    cin >> N;
    for (int i = 1; i <= N; ++i)
    {
        int L;
        cin >> L;
        while (L--)
        {
            string w;
            cin >> w;
            upd(w, i);
        }
    }

    int M;
    cin >> M;
    while (M--)
    {
        string q;
        cin >> q;
        calc(q);
    }
}

int main()
{
    ios ::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t--)
        solve();
    return 0;
}


发表于 2026-01-19 12:18:53 回复(0)