字符串最短公共祖先
题意:
求包含a,b两字符串的最小字符串的长度。
题解:
a,b两字符串互相进行两次kmp,满足以下三个条件:
a的后缀与b的前缀重合
a的前缀与b的后缀重合
a在b内或b在a内
代码:
#include <bits/stdc++.h> using namespace std; #define ll long long const int M = 1e6+5; char st[M],str[M]; int nex[M],la,lb; void getn(char *st){ int j=-1; nex[0]=-1; int le=strlen(st); for(int i=1;i<le;i++){ while(j>-1&&st[j+1]!=st[i]) j=nex[j]; if(st[j+1]==st[i]) j++; nex[i]=j; } } int kmp(char *st,char *str){ getn(st); int j=-1; int le=strlen(st),len=strlen(str); for(int i=0;i<len;i++){ while(j>-1&&st[j+1]!=str[i]) j=nex[j]; if(st[j+1]==str[i]) j++; if(j==le-1) return j; //中间 } return j; //前缀后缀 } int t; int main(){ scanf("%d",&t); while(t--){ scanf("%s %s",st,str); int sum=strlen(st)+strlen(str); memset(nex,0,sizeof(nex)); int a=kmp(st,str)+1; memset(nex,0,sizeof(nex)); int b=kmp(str,st)+1; // printf("%d %d\n",a,b); int maxx=(a>b)?a:b; int ans=sum-maxx; printf("%d\n",ans); } return 0; }