USACO Longest Prefix

来源:互联网 发布:java包装1年项目经验 编辑:程序博客网 时间:2024/05/22 01:43

  先将给出的集合元素构造成字典树,注意需要有危险节点的标志,然后对于主串,建立一个同样大小的bool型数组表示最远匹配到前多少位,假设为is,对于主串的每一个字符,如果此字符前is数组为false,则跳过,否则,从此字符往后匹配,若遇到危险节点,则is对应位置为true,并更新Max,需要注意的是主串需添加结束标志,对每一位往后进行匹配时需判断是否越界,代码:

/*ID: jinusac1PROG: prefixLANG: C++*/#include <iostream>#include <cstdio>#include <cstring>using namespace std;struct DicTree{char letter;//可省略,知识为了调试好调一些,其实没多大用int p[26];bool is;}t[20010];char key[11],sstr[200010];int slen=0,keylen[210],Max=0,nt=1;bool pre[200010]={false};int main(){freopen("prefix.in","r",stdin);freopen("prefix.out","w",stdout);t[0].is=false;memset(t[0].p,-1,sizeof(t[0].p));while(1){scanf("%s",key);if(key[0]=='.') break;int ptr=0;for(int i=0;key[i];i++){if(t[ptr].p[key[i]-'A']==-1){t[ptr].p[key[i]-'A']=nt;t[nt].letter=key[i];memset(t[nt].p,-1,sizeof(t[nt].p));t[nt].is=false;nt++;}ptr=t[ptr].p[key[i]-'A'];if(!key[i+1]) t[ptr].is=true;}}//构造字典树getchar();char c;while((c=getchar())!=EOF){if(c=='\n') continue;sstr[slen++]=c;}sstr[slen]='#';//结束标志pre[0]=true;for(int i=0;sstr[i]!='#';i++){if(!pre[i]) continue;int ptr=0,j=i;//0为头结点,即根while(ptr!=-1){ptr=t[ptr].p[sstr[j]-'A'];if(ptr!=-1){if(t[ptr].is){pre[j+1]=true;if(Max<(j+1)) Max=j+1;//更新Max}j++;if(sstr[j]=='#') break;//是否越界}}}cout<<Max<<endl;return 0;}


 

0 0
原创粉丝点击