#71 C

来源:互联网 发布:上海谷歌优化公司 编辑:程序博客网 时间:2024/05/15 03:07

      题目意思是在给定主串中找一个连续的子串,使其不包含任何完整的boring串,输出其长度和起始位置。

 

      这道题做得很失败。。。一开始就只想到用kmp匹配来标记好boring串的位置,设了4个状态,敲了180+行,结果还是wa。最后看了某牛的代码才知道可以用dp来做,其中dp[i]表示第i个下标起可以得到的最长子串长度,l[i]用来记录在第i个下标是否有boring串以其为起点,有则为其长度,反之是inf。最后从后往前扫一遍即可。dp方程为:

   len1 为主串长度

    dp[len1]=0;

  for  i=len1-1;i>=0;i--

    dp[i]=min(l[i]-1,dp[i]+1);

 

 

    以下是代码:

 

  1. #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    const int M=101010;
    const int N=100;
  2. int min(int a,int b) {return a<b?a:b;}
    const int inf=1<<29;
    char str[M],w[N];
    int l[M],dp[M];
    int n;
  3. int main()
    {
  4.  while(scanf("%s",str)==1)
     {
      int len1=strlen(str);
      int i,j,k;
      int len2;
      
  5. for(i=0;i<len1;i++)
       l[i]=inf;
      
  6. scanf("%d",&n);
     
  7.  for(i=0;i<n;i++)
      {
       scanf("%s",w);
       int len2=strlen(w);
       for(j=0;j<=len1-len2;j++)
       {
        if(l[j]<=len2) continue;
        for(k=0;k<len2 && w[k]==str[k+j];k++);
        if(k==len2) l[j]=len2;
       }
      }
      int ansx=len1;
      dp[len1]=0;
      
  8. for(i=len1-1;i>=0;i--)
      {
       dp[i]=min(l[i]-1,dp[i+1]+1);
       if(dp[ansx]<dp[i]) ansx=i;
      }
      
  9.   if(ansx==len1) ansx=0;
      printf("%d %d/n",dp[ansx],ansx);
     }
     return 0;
    }
原创粉丝点击