BerOS File Suggestion

Description

Polycarp is working on a new operating system called BerOS. He asks you to help with implementation of a file suggestion feature.

There are nn files on hard drive and their names are f1,f2,…,fn. Any file name contains between 1 and 8 characters, inclusive. All file names are unique.

The file suggestion feature handles queries, each represented by a string ss. For each query ss it should count number of files containing ssas a substring (i.e. some continuous segment of characters in a file name equals ss) and suggest any such file name.

For example, if file names are "read.me", "hosts", "ops", and "beros.18", and the query is "os", the number of matched files is 2(two file names contain "os" as a substring) and suggested file name can be either "hosts" or "beros.18".

Input

The first line of the input contains integer n (1≤n≤10000) — the total number of files.

The following nn lines contain file names, one per line. The ii-th line contains fi — the name of the i-th file. Each file name contains between 1 and 8 characters, inclusive. File names contain only lowercase Latin letters, digits and dot characters ('.'). Any sequence of valid characters can be a file name (for example, in BerOS ".", ".." and "..." are valid file names). All file names are unique.

The following line contains integer q (1≤q≤50000) — the total number of queries.

The following qq lines contain queries s1,s2,…,sq, one per line. Each sjsj has length between 1 and 8 characters, inclusive. It contains only lowercase Latin letters, digits and dot characters ('.').

Output

Print qq lines, one per query. The jj-th line should contain the response on the jj-th query — two values cjcj and tjtj, where

  • cj is the number of matched files for the jj-th query,
  • tj is the name of any file matched by the jj-th query. If there is no such file, print a single character '-' instead. If there are multiple matched files, print any.

思路

题意十分简单,给n个长度不超过8的字符串,q次询问,问每次给的字符串在n个字符串中出现的次数,并输出其中任意一个。

一开始考虑的是KMP直接暴力匹配,然后意料之内的TLE了。后面开始考虑每个字符串的长度不超过8,而且每次询问所给的字符串一定是在给定的字符串中的连续子串,因为是连续的所以如果将一个串分解的话长度为1的最多有8个,为2的最多有7个,以此类推。所以一个串最多可以分为4*9=36个。再因为n的上限是1e4,36*n也才3.6e5,于是考虑使用map将出现的次数,以及出现过的主串存起来。查询时直接输出对应的答案

substr(begin,length);这个函数之前的确不知道,因为这次是组队做,所以由队友提出了这个方便的截取子串的方法,其中两个参数分别为截取的起始位置和所需要截取的长度,经过测试,当截取长度超过剩余长度时,会直接将剩下的都截下,并不会报错。

AC代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <map>

using namespace std;

typedef long long LL;
const int MAXN = 1e5+10;

int n,m;
string str;

int main()
{
    map<string,int>mpsum;   //记录出现的次数
    map<string,string>mpstr;//记录子串对应的主串
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        cin >> str;
        map<string,string>mpcnt;//避免重复,记录每一个主串中出现过的子串
        for(int j=0;j<str.size();j++){//子串起始位置
            for(int k=1;k<str.size();k++){//子串长度
                mpcnt[str.substr(j,k)]=str.substr(j,k);
                mpstr[str.substr(j,k)]=str;
            }
        }
        map<string,string>::iterator it;
        for(it=mpcnt.begin();it!=mpcnt.end();it++){
            mpsum[it->second]++;
        }
        mpsum[str]++;
        mpstr[str]=str;
    }
    scanf("%d",&m);
    while(m--){
        string c;
        cin >> c;
        printf("%d ",mpsum[c]);
        if(mpsum[c]){
            cout << mpstr[c] << endl;
        }
        else{
            cout << "-" << endl;
        }
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值