题解 P1470 最长前缀 Longest Prefix
Posted thinkofblank
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 P1470 最长前缀 Longest Prefix相关的知识,希望对你有一定的参考价值。
首先看题,题目要求我们求最长匹配的长度,我们不妨如下思考:
? 对于字符串S,我们从第y位开始搜索(保证前y-1位一定可以是匹配)
? 从第y位开始生成字符串,若此时生成的字符串在P中出现过,则证明
? 此时的字符串可以被匹配到y+i的位置,我们再从y+i+1开始搜索便好了!
? 而问题的答案就是我们已到达的最大的一个y。
那么问题来了,如果按照上述说法搜索,复杂度不稳定,但一定会
? 超时的,有木有什么优化呢?
答案是有的(不然我写这个题解干什么呢?),我们注意到,如果
? 对于此时的y,我们曾经到达过,虽然到达的方式不同,但我们到达过,后
? 面我们进行搜索的过程与结果肯定是一样的,所以,我们就跳过就好啦!
? 而总的复杂度最高位O(n)(n为S串的长度),一下便是完整代码(加了点小优
? 化):
#include<bits/stdc++.h>
using namespace std;
map<string,bool>s;//一个map解千愁~就是<u>**速度慢了点**</u>,大佬请自行打**hash**
int x;
int ans=0;
int ams=0;
string l;
bool F=0;
bool come[200001];
inline void to_search(int now){
if(come[now]){//如果曾经搜索过此时的‘y’
return;//退出
}
come[now]=1;//标记搜索过此时的‘y’
if(now==x){
return;
}
string qu="";
for(int i=now;i<x;++i){
if(i-now>=ams){//如果现在加的元素大于了最长元素,之后一定不可能成立,于是跳过(虽然是小优化,也很强大有不有~)
return;
}
qu+=l[i];
if(s[qu]){//如果P集合中有此时的元素
F=1;//判断成立
if(i>ans){//记录答案
ans=i;
}
to_search(i+1);//从下一个y开始搜索
}
}
}
int main(){
int e=1;
while(cin>>l){
if(l=="."){
break;
}
s[l]=1;//标记元素存在
if(l.size()>ams){
ams=l.size();//记录最长元素(小优化第一步)
}
}
string yu="";
while(cin>>l){//输入字符串S
yu+=l;//将字符串S整合
}
l=yu;
x=l.size();//得到S的长度
to_search(0);//从第一个字符开始搜索
if(!F){//注意判断是否搜索过,第一个点的坑QWQ
printf("0");
return 0;
}
printf("%d",ans+1);//输出答案(记得加一,因为是从0开始搜的)
return 0;
}
以上是关于题解 P1470 最长前缀 Longest Prefix的主要内容,如果未能解决你的问题,请参考以下文章
Luogu P1470 最长前缀 Longest Prefix
P1470 [USACO2.3]最长前缀 Longest Prefix
Leetcode PHP题解--D134 14. Longest Common Prefix
leetcode 题解 || Longest Common Prefix 问题