Description
Input
Output
Sample Input
3 2 GATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 3 GATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATA GATACTAGATACTAGATACTAGATACTAAAGGAAAGGGAAAAGGGGAAAAAGGGGGAAAA GATACCAGATACCAGATACCAGATACCAAAGGAAAGGGAAAAGGGGAAAAAGGGGGAAAA 3 CATCATCATCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC ACATCATCATAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AACATCATCATTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
Sample Output
no significant commonalities AGATAC CATCATCAT
题目意思是:找出m个串中最长连续公共串,串长度要大于等于3,并且当最长公共串有多个,则输出字典序最小.
解析:这里假设有3个串,长度设短一点为8,程序只有16MS
1:ABCDAFKD 2:BCDAKJSA 3: KACBCDAD
以1串中的子串与2,3串匹配。分解1串成子串:
len=8: ABCDAFKD
len=7: ABCDAFK
BCDAFKD
len=6: ABCDAF
BCDAFK
CDAFKD
len=5: ABCDA
BCDAF
CDAFK
DAFKD
len=4: ABCD
BCDA
CDAF
DAFK
AFKD
len=3: 时己经不用判断了,最长公共串为BCDA。
就按上面的子串一一与2,3串进行匹配。
#include<stdio.h> char str[12][65],ch[65]; void panduan(int l,int r,int flog) { int i,j; if(flog==0) { for( i=0;l<=r;l++,i++) ch[i]=str[1][l]; return ; } for( i=0,j=l;j<=r;i++,j++) if(str[1][j]<ch[i]) break; if(j<=r) { for(i=0,j=l;j<=r;j++,i++) ch[i]=str[1][j]; } } int main() { int cas,m,l,r; scanf("%d",&cas); while(cas--) { scanf("%d",&m); for(int k=1;k<=m;k++) scanf("%s",str[k]); int len,mov,k,t,i,j,flog=0; for(len=60;len>=3;len--)//最长分共长度为len { l=0; r=len-1;//第1个串中最长公共串的最左,右 for(mov=0;mov<=60-len;mov++)//在长度为len下,在串1中有60-len种长度为len的串 { l=mov; r+=mov;//长度为len的串在串1中的位置 for(k=2;k<=m;k++)//与第2~m个串匹配 { for( t=0;t<=60-len;t++)//在第k个串中以t位置为带头进行匹配 { for(i=l,j=t;i<=r;j++,i++) if(str[1][i]!=str[k][j]) break;//在第k串中没找到完全匹配 if(i>r) break;//在第k串中找到匹配的串 } if(t>60-len) break;//在第k个串中没有找到匹配的那么一定不是公共串,那后串就不用找了 } if(k>m){//找到最长公共串 panduan(l,r,flog);//找到最长公共串中字典序最小的 flog=1; } r-=mov;//复原 } if(flog) break;//找到最长公共串 } if(flog) { for(i=0;i<len;i++) printf("%c",ch[i]); printf("\n"); } else printf("no significant commonalities\n"); } }