Description
从一个给定的串中删去(不一定连续地删去)0个或0个以上的字符,剩下的字符按原来的顺序组成的串是该串的字串。例如:“”, “a”, “aaa”,“bbb”,“xabb”,“xaaabbb”都是串“xaaabbb”的字串。(例子中的串不包括引号)
编程求N个非空串的最长公共子串的长度。
限制:2<=N<=100:N个串中的字符只会是数字0,1,…,9或小写字母a,b,…,z;每个串非空且最多含100个字符;N个串的长度的乘积不会超过30000。
编程求N个非空串的最长公共子串的长度。
限制:2<=N<=100:N个串中的字符只会是数字0,1,…,9或小写字母a,b,…,z;每个串非空且最多含100个字符;N个串的长度的乘积不会超过30000。
Input
文件第一行是一个整数T,表示测试数据的个数(1<=T<=10)。接下来T组测试数据。各族测试数据的第一行是一个整数Ni,表示第i数据中串的个数。各组测试数据的第2到N+1行中,每行一个串,串中不会有空格
,但行首和行未可能有空格,这些空格当然不算作串的一部分。
,但行首和行未可能有空格,这些空格当然不算作串的一部分。
Output
输出T行,每行一个数,第I行的数表示第I组测试数据中Ni的非空串的最长公共子串的长度
Sample Input
1 3 ab bc cd
Sample Output
0
题解
- 题目大意:给你n个字符串,求它们的最长公共子序列
- 显然可以用dp做
- 我们每次可以两两找最长公共子序列,新建一个字符串s[0]来储存
- 那么就可以直接找s[0]与s[i]的最长公共子序列
- 然后我们发现有个问题,就是在找到最长公共子序列的长度时,如果往回找到最长公共子序列
- 考虑记录转移状态:
- ①x[i]==y[i],f[i][j]=f[i-1][j-1]+1
- ②x[i]!=y[i] 且 f[i-1][j]>f[i][j-1] ,f[i][j]=f[i-1][j]
- ③x[i]!=y[i] 且 f[i-1][j]<f[i][j-1], f[i][j]=f[i][j-1]
代码
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 int len[110][110],step[110][110],t,m; 7 char s[110][110]; 8 void dp(char s1[110],char s2[110]) 9 { 10 memset(len,0,sizeof(len)); 11 memset(step,0,sizeof(step)); 12 int len1=strlen(s1),len2=strlen(s2); 13 for (int i=1;i<=len1;i++) 14 for (int j=1;j<=len2;j++) 15 { 16 if (s1[i-1]==s2[j-1]) 17 { 18 len[i][j]=len[i-1][j-1]+1; 19 step[i][j]=0; 20 } 21 else 22 if (len[i-1][j]>=len[i][j-1]) 23 { 24 len[i][j]=len[i-1][j]; 25 step[i][j]=1; 26 } 27 else 28 { 29 len[i][j]=len[i][j-1]; 30 step[i][j]=2; 31 } 32 } 33 int a=len1,b=len2,w=len[len1][len2]-1; 34 char s3[110]={}; 35 for (int i=1;i<=len[len1][len2];i++) 36 { 37 while (s1[a-1]!=s2[b-1]) 38 { 39 if (step[a][b]==0) a--,b--; 40 else 41 if (step[a][b]==1) a--; 42 else b--; 43 } 44 s3[w]=s1[a-1]; w--; 45 if (step[a][b]==0) a--,b--; 46 else 47 if (step[a][b]==1) a--; 48 else b--; 49 } 50 strcpy(s[0],s3); 51 m=len[len1][len2]; 52 } 53 int main() 54 { 55 scanf("%d",&t); 56 for (int k=1;k<=t;k++) 57 { 58 int n,o=0; 59 scanf("%d",&n); 60 for (int i=0;i<=n-1;i++) scanf("%s",s[i]); 61 for (int i=1;i<=n-1;i++) 62 { 63 dp(s[0],s[i]); 64 if (m==0&&o!=1) 65 { 66 o=1; 67 printf("0\n"); 68 } 69 } 70 if (o==0) printf("%d\n",m); 71 } 72 }