FZU Problem 1985 LCP Problem (字符串深度分析)

 Problem 1985 LCP Problem

 Problem Description

LCP (Longest Common Prefix), is defined as the longest common prefix of two strings. For example, LCP (“AC”, “ACOrz”) = “AC”, LCP (“WA”,”AC”) = “”.

Now you are given several DNA sequence. (Only contains ‘A’, ‘T’, ‘C’ and ‘G’).

You are expected to output the length of the LCP of two DNA sequence.

 Input

In the first line there is an integer T, indicates the number of test cases. (T <= 10)

In each case, the first line contains only one integer n, indicates the number of DNA sequence. (1 <= n <=100000, the number of letters in one test case is smaller than 100000)

Then one integer m, then m lines, each line contains two integers a,b ,indicates the index of the two DNA sequence. (0 <= m <= 100000, 0<= a,b <n)

 Output

For each case, output “Case idx: “first where idx is the case index start from 1 in a single line , then output m lines indicate the length of the LCP.

Sample Input
2
2
ATCG
AT
1
0 1
3
AT
ATT
ATTT
3
0 0
0 1
0 2
Sample Output

Case 1:
2
Case 2:
2
2
2

  题意非常简单,求串i 与 j 的最长公共前缀。

  1 、感觉建Trie树做法不科学,效率不高。

  2、 直接匹配串i ,串j 
  3、 开二维数组不可行。
  4、一个case里面出现字符的个数最大为100000 ,
  5、 用一维的串存, 加 结束符’\0‘  ,并做标记 。
  6.   str  =    abcd'\0'efg     则  strlen(str)  =  4   , strlen(str+5) = 3 .

const int Max_N  = 100008 ;
char str[Max_N*5]  ;
int  id[Max_N] ;

int  LCP(char *s1 , char *s2){
     int ans = 0 ;
     while(*s1 != '\0' && *s2 != '\0'  && *s1 == *s2){
          s1++ ;
          s2++ ;
          ans ++ ;
     }
     return ans ;
}

void read_str(int n){
     int idx = 0 ;
     char * p ;
     p = NULL ;
     for(int i = 0 ; i < n ; i++){
         p = str+idx ;
         id[i] = idx ;
         scanf("%s" , p) ;
         idx = idx + strlen(p) + 1 ;
     }
    /* for(int i = 0 ; i <= 10 ; i++)
         printf("%c" ,str[i]=='\0' ? '*' : str[i]) ;
      puts("----") ;
     for(int i = 0 ; i < n ; i++)
        printf("%d %d\n" ,i , id[i]) ;*/
}

int  main(){
     int n , m , t , x , y , cas ;
     scanf("%d" , &t) ;
     for(cas = 1 ; cas <= t ; cas++){
         scanf("%d" ,&n) ;
         read_str(n) ;
         printf("Case %d:\n" , cas) ;
         scanf("%d" ,&m) ;
         while(m--){
             scanf("%d%d" ,&x ,&y) ;
             printf("%d\n" ,LCP(str+id[x] , str+id[y])) ;
         }
     }
     return 0 ;
}


read_str()  直观 :






                                              





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值