洛谷[3879] [TJOI2010]阅读理解(trie树模板)

来源:互联网 发布:金庸群侠传 for mac 编辑:程序博客网 时间:2024/06/05 08:38

题目链接:luogu3879


P3879 [TJOI2010]阅读理解

时空限制 2s / 128MB


题目描述

英语老师留了N篇阅读理解作业,但是每篇英文短文都有很多生词需要查字典,为了节约时间,现在要做个统计,算一算某些生词都在哪几篇短文中出现过。

输入输出格式

输入格式:

第一行为整数N,表示短文篇数,其中每篇短文只含空格和小写字母。按下来的N行,每行描述一篇短文。每行的开头是一个整数L,表示这篇短文由L个单词组成。接下来是L个单词,单词之间用一个空格分隔。然后为一个整数M,表示要做几次询问。后面有M行,每行表示一个要统计的生词。

输出格式:

对于每个生词输出一行,统计其在哪几篇短文中出现过,并按从小到大输出短文的序号,序号不应有重复,序号之间用一个空格隔开(注意第一个序号的前面和最后一个序号的后面不应有空格)。如果该单词一直没出现过,则输出一个空行。

输入输出样例

输入样例#1:

39 you are a good boy ha ha o yeah13 o my god you like bleach naruto one piece and so do i11 but i do not think you will get all the points5youioallnaruto

输出样例#1:

1 2 32 31 232

说明

对于30%的数据,1 ≤ M ≤ 1,000对于100%的数据,1 ≤ M ≤ 10,000,1 ≤ N ≤ 100每篇短文长度(含相邻单词之间的空格) ≤ 5,000 字符,每个单词长度 ≤ 20 字符每个测试点时限2秒

题解 :
这道题,本来第一眼看过去是用trie树来写的。但是看了一下数据范围就直接开了map暴力跑了过去。当然用trie来练练手也是可以的。大概就是模拟这么一个过程,将所有的单词在哪篇文章出现过都存起来,直接输出需要询问的单词,但如果是没有出现过还要注意输出空行

代码(map):

#include<iostream>#include<map>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define ll long longinline int read(){    int x = 0,f = 1;char ch = getchar();    while(ch < '0' || ch > '9'){if(ch == '-')f = -1; ch = getchar();}    while(ch >= '0' && ch <= '9'){x = x*10+ch-'0'; ch = getchar();}    return x*f;}map<string,int> mp;int heap[500000][101];int top[500000];int n,m,cnt;int main(){    n = read(); string s;    for(int i = 1;i <= n;i++){        int l = read();        for(int j = 1;j <= l;j++){            cin>>s;            if(mp[s] == 0) mp[s] = ++cnt;            int x = mp[s];            if(heap[x][top[x]] == i) continue;            heap[x][++top[x]] = i;        }    }    m = read();    for(int i = 1;i <= m;i++){        cin>>s;        int x = mp[s];        if(top[x] == 0) puts("");        else{            for(int i = 1;i < top[x];i++)                printf("%d ",heap[x][i]);            printf("%d\n",heap[x][top[x]]);             }    }    return 0;}

代码(trie):

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define ll long longinline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}int tri[26][5000001];bool show[101][5000001];int n,cnt;void insert(int x){    char s[25];    scanf("%s",s);    int len = strlen(s);    int now = 0;    for(int i = 0;i < len;i++){        if(tri[s[i]-'a'][now] == 0) tri[s[i]-'a'][now] = ++cnt;        now = tri[s[i]-'a'][now];    }    show[x][now] = true;}void check(){    char s[25];    scanf("%s",s);    bool flag = true;    int len = strlen(s);    int now = 0;    for(int i = 0;i < len;i++){        if(tri[s[i]-'a'][now] == 0){            flag = false;            break;        }        now = tri[s[i]-'a'][now];    }    if(flag){        for(int i = 1;i < n;i++)            if(show[i][now])                printf("%d ",i);        if(show[n][now])            printf("%d",n);    }    puts("");}int main(){    n = read();    for(int i = 1;i <= n;i++){        int l = read();        for(int j = 1;j <= l;j++)            insert(i);    }    int m = read();    for(int i = 1;i <= m;i++)        check();    return 0;}
原创粉丝点击