zoukankan      html  css  js  c++  java
  • lightOJ 1258 Making Huge Palindromes(KMP)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1258

    就是求逆串和原串的匹配长度

    答案就是原串长度的2倍减去匹配长度即可

    第一次我将原串接在逆串后面然后一次求失败函数得当前串的f[len1](假设当前总串长度为len1)那么答案即为了len1-f[len1],如果f[len1]>=len ,那么答案为len

    但是wrong了,,不知道原因

    第二次就直接匹配原串和逆串然后就AC了

    我把错误代码和正确代码都贴出来,有时间再思考为什么第一个方法错吧,有哪位朋友看到也可以指导,谢啦

    错误代码:

     1 #include<iostream>
     2 #include<cstdlib>
     3 #include<cstdio>
     4 #include<cstring>
     5 #define maxn 1000005
     6 using namespace std;
     7 char s[maxn];
     8 char s1[maxn*2];
     9 int len;
    10 int len1;
    11 int f[maxn*2];
    12 void callfail()
    13 {
    14     int i,j=0,k=-1;
    15     f[0]=-1;
    16     while(j<len1)
    17     {
    18         if(k==-1 || s1[j]==s1[k])
    19         {
    20                 k++;j++;
    21                 f[j]=k;
    22         }
    23         else k=f[k];
    24     }
    25 }
    26 int main()
    27 {
    28     int t;
    29     while(scanf("%d",&t)!=EOF)
    30    {
    31        int iCase=1;
    32      while(t--)
    33      {
    34            printf("Case %d: ",iCase++);
    35            s[0]='';
    36            s1[0]='';
    37            scanf("%s",s);
    38            len=strlen(s);
    39            for(int i=0;i<len;i++)
    40               s1[i]=s[len-1-i];
    41               s1[len]='';  
    42            strcat(s1,s);
    43            len1=strlen(s1);
    44            s1[len1]='';
    45            callfail();
    46            if(f[len1]>=len)
    47            cout<<len<<endl;
    48            else
    49            cout<<len1-f[len1]<<endl;
    50      }
    51    }
    52    return 0;
    53 }

    正确代码:

     1 #include <cstdio>  
     2 #include <cstring>
     3 using namespace std;
     4 const int maxn = 1000005;  
     5 char a[maxn];  
     6 char b[maxn];  
     7 int f[maxn];  
     8   
     9   
    10 void callfail()  
    11 {  
    12     int len= strlen(b);  
    13     f[0] =-1;
    14     int j=0,k=-1; 
    15     while(j<len) 
    16     {
    17        if(k==-1 || b[k]==b[j])
    18        {
    19           k++;j++;
    20           f[j]=k;
    21        }
    22        else k=f[k];
    23     }
    24 }  
    25 int kmp()  
    26 {  
    27     int la = strlen(a);  
    28     int lb = strlen(b);  
    29     callfail();  
    30     int i=0,j = 0;  
    31     while(i<la && j<lb)
    32     {
    33       if(j==-1 || a[i]==b[j])
    34       {
    35            i++;j++;
    36       }
    37       else j=f[j];
    38     }
    39     return la + lb - j;  
    40 }  
    41   
    42   
    43 int main()  
    44 {  
    45     int t;  
    46     scanf("%d", &t);  
    47     for (int i = 1; i <= t; i++)  
    48     {  
    49         scanf("%s", a);  
    50         int l = strlen(a);  
    51         for (int j = 0; j < l; j++)  
    52         {  
    53             b[l-j-1] = a[j];  
    54         }  
    55         b[l] = '';  
    56         printf("Case %d: %d
    ", i, kmp());  
    57     }  
    58     return 0;  
    59 }  
  • 相关阅读:
    POJ 1611 The Suspects
    POJ 2001 Shortest Prefixes(字典树)
    HDU 1251 统计难题(字典树 裸题 链表做法)
    G++ C++之区别
    PAT 乙级 1013. 数素数 (20)
    PAT 乙级 1012. 数字分类 (20)
    PAT 乙级 1009. 说反话 (20)
    PAT 乙级 1008. 数组元素循环右移问题 (20)
    HDU 6063 17多校3 RXD and math(暴力打表题)
    HDU 6066 17多校3 RXD's date(超水题)
  • 原文地址:https://www.cnblogs.com/xiaozhuyang/p/lightOJ1258.html
Copyright © 2011-2022 走看看