• Substrings POJ


    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 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 

    题意:求出所有串中,最长的子串长度(子串不一定要相等,子串反转后相等也行)

    思路:二分子串长度,将每个串和其反串合并成一个数组,然后求后缀数组,并记录每个串长度前缀和(长度前缀和指的是加上该串和其反串后整个字符长)
    然后对于ht数组,如果当前ht数组所对应的sa【i】和sa【i-1】出现的串之前没出现过,那么种类数+1,直到种类数 == n
    如果中途发现ht < mid 那么就清空之前所记录的信息,重新匹配


      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<algorithm>
      6 using namespace std;
      7 
      8 int T,n;
      9 const int maxn = 2e5+5;
     10 string s;
     11 int sa[maxn],t[maxn],t2[maxn],c[maxn],len[105];
     12 
     13 void build_sa(int n,int m)
     14 {
     15     int i,*x=t,*y=t2;
     16     for(i=0; i<m; i++)c[i]=0;
     17     for(i=0; i<n; i++)c[x[i]=s[i]]++;
     18     for(i=1; i<m; i++)c[i]+=c[i-1];
     19     for(i=n-1; i>=0; i--)sa[--c[x[i]]]=i;
     20     for(int k=1; k<=n; k<<=1)
     21     {
     22         int p=0;
     23         for(i=n-k; i<n; i++)y[p++]=i;
     24         for(i=0; i<n; i++)if(sa[i] >= k)y[p++]=sa[i]-k;
     25         for(i=0; i<m; i++)c[i] = 0;
     26         for(i=0; i<n; i++)c[x[y[i]]]++;
     27         for(i=1; i<m; i++)c[i]+=c[i-1];
     28         for(i=n-1; i>=0; i--)sa[--c[x[y[i]]]] = y[i];
     29         swap(x,y);
     30         p=1,x[sa[0]]=0;
     31         for(i=1; i<n; i++)
     32             x[sa[i]] = y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k] == y[sa[i]+k]?p-1:p++;
     33         if(p>=n)break;
     34         m=p;
     35     }
     36 }
     37 
     38 int ht[maxn],rk[maxn];
     39 
     40 void getHeight(int n)
     41 {
     42     int i,j,k=0;
     43     for(i=0; i<n; i++)rk[sa[i]] = i;
     44     for(i=0; i<n-1; i++)
     45     {
     46         if(k)k--;
     47         if(s[i] == '$')continue;
     48         int j = sa[rk[i]-1];
     49         while(s[i+k] == s[j+k] && s[i+k] != '$')k++;
     50         ht[rk[i]] = k;
     51     }
     52 }
     53 
     54 bool vis[105];
     55 bool check(int mid)
     56 {
     57     memset(vis,0,sizeof(vis));
     58     int cnt=0;
     59     bool flag = 0;
     60     for(int i=1; i<len[n]; i++)
     61     {
     62         if(ht[i] >= mid && s[sa[i]] != '$')
     63         {
     64 
     65             for(int j=1; j<=n; j++)
     66             {
     67                 if(!flag)
     68                 {
     69                     //printf("%d $$$$ %d    %d
    ",sa[i-1]+1,len[j-1],len[j]);
     70                     if(sa[i-1]+1 > len[j-1] && sa[i-1]+1 < len[j])if(!vis[j])vis[j]=1,cnt++,flag = 1;
     71                 }
     72                 if(sa[i]+1 > len[j-1] && sa[i]+1 < len[j])if(!vis[j])vis[j] = 1,cnt++;
     73             }
     74           //  printf("============================================
    ",flag);
     75         }
     76         else
     77         {
     78             if(cnt == n)return 1;
     79             cnt = 0;
     80             flag = 0;
     81             memset(vis,0,sizeof(vis));
     82         }
     83     }
     84     if(cnt == n)return 1;
     85     return 0;
     86 }
     87 char tmp[200];
     88 int main()
     89 {
     90     scanf("%d",&T);
     91     while(T--)
     92     {
     93         scanf("%d",&n);
     94         s.clear();
     95         for(int i=1; i<=n; i++)
     96         {
     97             scanf("%s",tmp);
     98             int tmp_len = strlen(tmp);
     99             s+=tmp;
    100             s+='$';
    101             reverse(tmp,tmp+tmp_len);
    102             s+=tmp;
    103             s+='$';
    104             len[i] = s.length();
    105         }
    106        // for(int i=1;i<=n;i++)printf("%d =========
    ",len[i]);
    107 //        if(n == 1)
    108 //        {
    109 //            printf("%d
    ",len[1]/2-1);
    110 //            continue;
    111 //        }
    112         build_sa(len[n],130);
    113         getHeight(len[n]);
    114         int L = 1,R = len[n];
    115         int pos = 0;
    116         while(L <= R)
    117         {
    118             int mid = (L+R)/2;
    119             if(check(mid))pos = mid,L=mid+1;
    120             else R = mid-1;
    121         }
    122         cout << pos << endl;
    123     }
    124 
    125 }
    View Code
  • 相关阅读:
    PHP实现栈(Stack)数据结构
    为什么推荐std::string而不是char*
    PHP实现插入排序算法
    OpenCms Application dev-ref
    OpenCMS integration with Spring MVC--reference
    安装opencms时遇到问题及解决方法
    Java ZIP File Example---refernce
    Top 10 Algorithms for Coding Interview--reference
    JVMInternals--reference
    java code to byte code--partone--reference
  • 原文地址:https://www.cnblogs.com/iwannabe/p/11483455.html
Copyright © 2020-2023  润新知