列表

详情


NC25831. y大的字符串

描述

题目背景

           y大怎么又ak了ioi啊
                                       ————QAQ

题目描述

y大对字符串产生了一定的兴趣,他能把KMP打的倒背如流,然后他也迷上了splay。然而不尽人意的是,y大的字符串匹配题还没有做完,他必须去做字符串匹配题。

在老师小s布置的的作业题上有一道题“Search”的描述是这样的:

输入n,m,

下面给n个长度小于10的字符串

再给m个大小小于1M的文本 如果文本串的一个前缀能被那n个长度小于10的字

符串拼凑出来(n个长度小于10的字符串每个都允许使用多次),则称这个文本串的那个前缀是能被解释的,

若有串ab,那abab的前缀有a,ab,aba,abab,其中a不能被ab解释,ab可以被自己解释,aba不行,abab可以被ab解释

求 能被解释的 最长的前缀 的长度 和 在能被解释的 最长的前缀的长度 中最长的回文串的长度。

y大看了一眼,认为十分简单,在1000ms内就秒掉了这道题,然后便去颓《splay》了,而蒟蒻的水宝宝却做不出这道题,便求助于你。

保证所有字母均为小写


注:本系列题不按难度排序哦

输入描述

第一行n,m 后n行为长度小于10的字符串

再后m行,m个大小小于1M的文本

输出描述

m行,每行对应一个询问 需要输出两个整数,第一个数代表 能被解释的 最长的前缀 的长度。第二个数代表在能被解释的 最长的前缀的长度 中最长的回文串的长度,具体见样例解释

示例1

输入:

4 3
ab
abb
abba
abc
abababab
abbbbba
ccccccc

输出:

8 7
3 2
0 0

说明:

abababab都可以被解释,最长回文串是abababa,故输出8和7

abbbbba只有abb可以被解释,最长回文串是bb,故输出3和2

ccccccc没有可以被解释的前缀,输出0和0

原站题解

import java.util.Scanner;
public class Main {
public static void main(String[] arg) {
Scanner scanner = new Scanner(System.in);
// todo
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

C++14(g++5.4) 解法, 执行用时: 60ms, 内存消耗: 20300K, 提交时间: 2019-07-01 09:26:44

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = 1e7+5;
char ss[maxn],snew[maxn*2];
int nxt[maxn][30];
int endd[maxn],p[maxn*2];
int tot=1;
void insert(char *s){
int len =strlen(s);
int u = 0;
for(int i=0;i<len;i++){
int id = s[i];
if(nxt[u][id]==0)nxt[u][id] = ++tot;
u = nxt[u][id];
}
endd[u] =1;
}
int query(char *ss,int len){
int u=0,res = 0;
for(int i=0;i<len;i++)
{
int t = nxt[u][ss[i]];
u =t;
if(endd[u])
{
res = i+1;
if(i+1==len)break;
if(nxt[t][ss[i+1]]==0)u=0;
}
if(t==0)break;
}
return res;
}
int init(int len){
int j=2;
snew[0]='$',snew[1]='#';
for(int i=0;i<len;i++){
snew[j++]=ss[i];
snew[j++] = '#';
}
snew[j] = '\0';
return j;
}
int Man(int len) {
int len_max = -1,mx=0,id;
for(int i=1;i<len;i++)
{
p[i] = mx>i ?min(p[id*2-i],mx-1) :1 ;
while(snew[p[i]+i]==snew[i-p[i]])
p[i]++;
if(p[i]+i>mx)
{
id = i;
mx = p[i] + i;
}
len_max= max(len_max,p[i]-1);
}
return len_max;
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%s",ss);
insert(ss);
}
while(m--){
scanf("%s",ss);
int s1 = query(ss,strlen(ss));
int s2 = Man(init(s1));
cout<<s1<<" "<<s2<<endl;
}
}

C++11(clang++ 3.9) 解法, 执行用时: 44ms, 内存消耗: 10340K, 提交时间: 2020-03-18 13:03:18

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=1e7+5;
char ss[maxn],snew[maxn*2];
int nxt[maxn][30];
int endd[maxn],p[maxn*2];
int tot=1;
void insert(char *s)
{
int len=strlen(s);
int u=0;
for(int i=0;i<len;i++)
{
int id=s[i];
if(nxt[u][id]==0) nxt[u][id]=++tot;
u=nxt[u][id];
}
endd[u]=1;
}
int query(char *ss,int len)
{
int u=0,res=0;
for(int i=0;i<len;i++)
{
int t=nxt[u][ss[i]];
u=t;
if(endd[u])
{
res=i+1;
if(i+1==len) break;
if(nxt[t][ss[i+1]]==0) u=0;
}
if(t==0) break;
}
return res;
}
int init(int len)
{
int j=2;
snew[0]='$',snew[1]='#';
for(int i=0;i<len;i++)
{
snew[j++]=ss[i];
snew[j++]='#';
}
snew[j]='\0';
return j;
}
int Man(int len)
{
int len_max=-1,mx=0,id;
for(int i=1;i<len;i++)
{
p[i]=mx>i?min(p[id*2-i],mx-1):1;
while(snew[p[i]+i]==snew[i-p[i]])
p[i]++;
if(p[i]+i>mx)
{
id=i;
mx=p[i]+i;
}
len_max=max(len_max,p[i]-1);
}
return len_max;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%s",ss);
insert(ss);
}
while(m--)
{
scanf("%s",ss);
int s1=query(ss,strlen(ss));
int s2=Man(init(s1));
cout<<s1<<" "<<s2<<endl;
}
}

上一题