HDU 4300 Clairewd’s message

这题比赛时,题意看了N久才看懂,囧。。。

算法又错了两次:

错误算法:

1. 用二分找密文长度。。

2.用只求了一次next函数找最长前缀匹配后缀,忽略了其可能有交集,在这题中是不允许的。。

正确算法:

饶了这么多弯,终于回到正道了,求一次KMP就可以解决。

用截获的文本后半段做主串,用前半段做模式串。

用KMP求出其最长匹配主串的长度。

View Code
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char str[101000];
char st[101000];
char temp1[101000];
char temp2[101000];
char hash[101000];
int next[101000];

void get_next( )
{
   int len = strlen( st + 1);
   int i = 1, j = 0;
   next[1] = 0;
   while( i <  len )
   {
      if( st[i] == st[j] || j == 0 )
      {
         ++i,++j;
         next[i] = j;    
          
      } 
      else
         j = next[j];      
          
   }     
     
}
//记录最多能匹配的字符个数 
int kmp(char *A, char *B)
{
   int len1 = strlen(A + 1);
   int len2 = strlen(B + 1);
   int i = 1, j = 1;
   while( i <= len1 && j <= len2 )
   {
      if( A[i] == B[j] || j == 0 )
      {
          if( i == len1 )
          return j;
          ++i, ++j;    
      }
      else
      {
          j = next[j];
      }
          
   }
   return 0; 
}


void HASH( )
{
  int len = strlen( str + 1);
  int num = 0;
  for( int i = 1; i <= len; i++)
  {
      hash[str[i]-'a'] = 'a' + num++;     
  }
     
}

int main( )
{
  int N;
  scanf("%d",&N);
  while( N-- )
  {
     scanf("%s%s",str+1,st+1);
     HASH( );
     memset(next, 0, sizeof(next));
     get_next( );
     int len = strlen(st+1);
     for( int i = 1; i <= len /2 + 1; i++)
        temp1[i] = hash[st[i]-'a'];
     temp1[len+1]='\0';
     /*
     int n = 1;
     if( len == 1 )
     {
        printf("%c%c\n",st[1], hash[st[1]-'a']);    
        continue;
     }
     
     for( int i = (len+1)/2; i <= len; i++)
       temp2[n++] = st[i];
     temp2[n] = '\0';
     */
     strcpy(temp2 + 1, st + (len + 1 ) / 2 + 1);
     int n = kmp(temp2, temp1);
     printf("%s",st + 1);
     for( int i = n + 1; i <= len - n; i++)
     {
        printf("%c",hash[st[i]-'a']);     
     }
     puts("");
  }   
  return 0;    
}

posted on 2012-07-20 22:22  more think, more gains  阅读(179)  评论(0编辑  收藏  举报

导航