标签:
题意是给出一些子串,用这些子串能拼出一个S的前缀来,问这个前缀最长能有多长。
做法是,从S的第一个元素开始扫,到S[i]时,查看每一个长度不大于i的子串,然后检查这个子串能否和以i为结尾,长度与这个子串长度相同的S的子串匹配,
若能匹配,则检查在以S[i-子串长度] 为结尾处能否找到以前匹配到S[i-子串长度]的标记,
/*
ID: modengd1
PROG: prefix
LANG: C++
*/
#include <iostream>
#include <string>
#include <cstring>
#include <stdio.h>
#include <memory.h>
#include <vector>
using namespace std;
int main()
{
freopen("prefix.in","r",stdin);
freopen("prefix.out","w",stdout);
vector<string> elements;
string S,element;
bool endTag[200001];
char temp;
int ans=0;
memset(endTag,false,sizeof(endTag));
while(true)//循环输入多个元素
{
element.clear();
while(scanf("%c",&temp)&&temp!=‘ ‘&&temp!=‘\n‘)
{
element.push_back(temp);
}
if(element[0]==‘.‘)
break;
elements.push_back(element);
}
while(scanf("%c",&temp)!=EOF)//输入S
{
if(temp==‘\n‘)
continue;
S.push_back(temp);
}
endTag[0]=true;
for(int i=1;i<=S.size();i++)
{
for(int j=0;j<elements.size();j++)
{
string now=elements[j];
bool ismath=true;
if(now.size()>i)
break;
//检查当前元素是否能以i结尾的,长度为now.size()的S的字串匹配
for(int k=now.size()-1;k>=0;k--)
{
if(S[i-1-k]!=now[now.size()-k-1])
{
ismath=false;
break;
}
}
//如果能匹配,检查是否存在以前匹配过的i-now.szie()的结尾标记
if(ismath&&endTag[i-now.size()])
{
endTag[i]=true;
ans=i;
break;
}
}
}
cout<<ans<<endl;
return 0;
}
能找到的话说明可以在S[i]处加标记。最后找到加的最远的一个标记就是题目要的答案。
标签:
原文地址:http://www.cnblogs.com/modengdubai/p/4781939.html