1. 程式人生 > >HDU:Substrings

HDU:Substrings

Substrings

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 9758    Accepted Submission(s): 4623
Problem Description You are given a number of case-sensitive strings of alphabetic characters, find the largest string X, such that either X, or its inverse can be found as a substring of any of the given strings.
Input The first line of the input file contains a single integer t (1 <= t <= 10), the number of test cases, followed by the input data for each test case. The first line of each test case contains a single integer n (1 <= n <= 100), the number of given strings, followed by n lines, each representing one string of minimum length 1 and maximum length 100. There is no extra white space before and after a string.
Output There should be one line per test case containing the length of the largest string found.
Sample Input 2 3 ABCD BCDFF BRCD 2 rose orchid Sample Output 2 2題目大意:
求最長公共子串的長度,但是題目要求有些特殊,例第一組,最長公共子串為CD,長度為2,第二組,長度也是2,這個串是第一個中的ro和第二個中的or,也就是你過來這個穿與正序的相同也算是公共子串。解題思路:string.h標頭檔案中有一個strstr(str1,str2)這個函式,意思是查詢str2在str1中是否存在,如果存在就返回真,不存在就返回假。現在就可以用這個。開一個二維陣列存放這些字串,先找出這些字串中最短的那一串,因為公共子串的最大長度最多與最短的那一串是相等的,則我們可以通過求出最短的那個字串中的每一個子串求這個子串在那些字串中是否都存在,如果都存在,說明這是這些字串的一個公共子串,如果在比較的時候發現有一個不符合的話,就結束當次迴圈,對每次求得的長度與最大長度相比,不斷更新最大長度。
題目程式碼:#include<stdio.h>#include<string.h>int main(){    char str[110][110],s1[110],s2[110]; //str用來存放所有的字串,s1,存放正序的串,s2存放逆序的串    int t,n,mmin,num,len,mmax,i,j,k,l,flag;     scanf("%d",&t); //t組測試資料    while(t--)    {        mmin = 1000; //最小長度賦1000,因為每個串都不會超過1000個字元        mmax =  0;    //公共子串的最大長度賦為0,頂多n個串沒有一個公共序列        num = 0; //最短的串的號初始化為0        scanf("%d",&n);        for(i = 0;i < n; i++)        {            scanf("%s",str[i]); //輸入n個字串            len = strlen(str[i]); //測每一個新輸入的字串的長度            if(len < mmin) //如果當前長度比最小長度小,那麼我更新最小長度,並更新最小長度的序號            {                mmin = len;  //最短的那個字串的長度                num = i;     //最短的字串的序號            }        }       for(i = 0;i < mmin; i++)       {           for(j = i;j < mmin; j++)           {                flag=1; //假設這個串是n個串的公共子串                for(k = i;k <= j; k++) //每次求i~j之間的序列                {                    s1[k-i] = s2[j-k] = str[num][k]; //s1正序,s2為當前子序列的你序列                }                s1[j-i+1] = s2[j-i+1] = '\0'; //在結尾加結束符號                //printf("%s %s\n",s1,s2); //這是判斷自己求子串的正確性的                len=strlen(s1); //測子串長度                for(l = 0;l < n; l++) //在n個字串中進行查詢                {                    if(!strstr(str[l],s1)&&!strstr(str[l],s2)) //除非正著逆著都沒有查到,我就結束                    {                        flag = 0; //有一個不是,說明這個串就不是公共子串                        break; //直接結束                    }                }                if(flag) //如果是,與最大長度比較,並更新最大值                {                    if(len > mmax)                        mmax = len;                }           }       }       printf("%d\n",mmax);    }    return 0;}