zoukankan      html  css  js  c++  java
  • 3409: [Usaco2009 Oct]Barn Echoes 牛棚回声

    3409: [Usaco2009 Oct]Barn Echoes 牛棚回声

    Time Limit: 3 Sec  Memory Limit: 128 MB
    Submit: 57  Solved: 47
    [Submit][Status][Discuss]

    Description

    奶牛们灰常享受在牛栏中哞叫,因为她们可以听到她们哞声的回音。虽然有时候并不能完全听到完整的回音。Bessie曾经是一个出色的秘书,所以她精确地纪录了所有的哞叫声及其回声。她很好奇到底两个声音的重复部份有多长。

    输入两个字符串(长度为1到80个字母),表示两个哞叫声。你要确定最长的重复部份的长度。两个字符串的重复部份指的是同时是一个字符串的前缀和另一个字符串的后缀的字符串。

    我们通过一个例子来理解题目。考虑下面的两个哞声:

        moyooyoxyzooo
        yzoooqyasdfljkamo
    

    第一个串的最后的部份"yzooo"跟第二个串的第一部份重复。第二个串的最后的部份"mo"跟第一个串的第一部份重复。所以"yzooo"跟"mo"都是这2个串的重复部份。其中,"yzooo"比较长,所以最长的重复部份的长度就是5。

    Input

    两行: 每一行是1个字符串表示奶牛的哞声或它的回声。

    Output

    第一行: 包含一个单独的整数表示输入的2个字符串中,一个字符串的前缀和另一个字符串的后缀的最长的重复部份的长度。

    Sample Input


    abcxxxxabcxabcd
    abcdxabcxxxxabcx

    Sample Output

    11

    "abcxxxxabcx"是第一个字符串的前缀和第二个字符串的后缀。

    HINT

     

    Source

    Gold

    题解:不知道bzoj啥时候冒出来一堆普及组的题目QAQ

    要是想A的话太容易了,所以还是瞎搞搞来连连脑洞吧

    方法一:直接( Oleft({N}^{2} ight) )瞎搞。。。(PS:不要问我为啥只有一层循环,事实上copy的复杂度是O(N)的)

     1 /**************************************************************
     2     Problem: 3409
     3     User: HansBug
     4     Language: Pascal
     5     Result: Accepted
     6     Time:0 ms
     7     Memory:416 kb
     8 ****************************************************************/
     9  
    10 var
    11    i,j,k,l,m,n:longint;
    12    s1,s2,s3:ansistring;
    13 function max(x,y:longint):longint;
    14          begin
    15               if x>y then max:=x else max:=y;
    16          end;
    17 begin
    18      readln(s1);
    19      readln(s2);l:=0;
    20      for i:=max(length(s2)-length(s1)+1,1) to length(s2) do
    21          begin
    22               s3:=copy(s2,i,length(s2)+1-i);
    23               if copy(s1,1,length(s2)+1-i)=s3 then
    24                  begin
    25                       l:=length(s2)+1-i;
    26                       break;
    27                  end;
    28          end;
    29      for i:=max(length(s1)-length(s2)+1,1) to length(s1) do
    30          begin
    31               s3:=copy(s1,i,length(s1)+1-i);
    32               if copy(s2,1,length(s1)+1-i)=s3 then
    33                  begin
    34                       l:=max(l,length(s1)+1-i);
    35                       break;
    36                  end;
    37          end;
    38      writeln(l);
    39      readln;
    40 end.     

    方法二:这是我第一反应的做法(但是N<=80是什么节奏= =)——字符串哈希(哈希大法好OTL),于是瞎搞搞,很基础的。。。(本人实测N<=3000000都能1s内出来)

     1 /**************************************************************
     2     Problem: 3409
     3     User: HansBug
     4     Language: Pascal
     5     Result: Accepted
     6     Time:0 ms
     7     Memory:4944 kb
     8 ****************************************************************/
     9  
    10 const p=314159;q=951413;
    11 var
    12    i,j,k,l,m,n,x0,y0,x,y:longint;
    13    list,a,b:array[0..5000000,1..2] of int64;
    14    s1,s2:ansistring;
    15 function max(x,y:longint):longint;
    16          begin
    17               if x>y then max:=x else max:=y;
    18          end;
    19  
    20 begin
    21      list[0,1]:=1;list[0,2]:=1;
    22      readln(s1);
    23      readln(s2);l:=0;
    24      n:=max(length(s1),length(s2))+1;
    25      for i:=1 to n do
    26          begin
    27               list[i,1]:=(list[i-1,1]*p) mod q;
    28               list[i,2]:=(list[i-1,2]*q) mod p;
    29          end;
    30      a[0,1]:=0;a[0,2]:=0;
    31      for i:=1 to length(s1) do
    32          begin
    33               a[i,1]:=(a[i-1,1]+(list[i,1]*ord(s1[i])) mod q) mod q;
    34               a[i,2]:=(a[i-1,2]+(list[i,2]*ord(s1[i])) mod p) mod p;
    35          end;
    36      b[0,1]:=0;b[0,2]:=0;
    37      for i:=1 to length(s2) do
    38          begin
    39               b[i,1]:=(b[i-1,1]+(list[i,1]*ord(s2[i])) mod q) mod q;
    40               b[i,2]:=(b[i-1,2]+(list[i,2]*ord(s2[i])) mod p) mod p;
    41          end;
    42      for i:=max(1,length(s1)-length(s2)+1) to length(s1) do
    43          begin
    44               j:=length(s1)-i+1;
    45               x:=(list[i-1,1]*b[j,1]) mod q;
    46               y:=(list[i-1,2]*b[j,2]) mod p;
    47               x0:=((a[length(s1),1]-a[i-1,1]) mod q+q) mod q;
    48               y0:=((a[length(s1),2]-a[i-1,2]) mod p+p) mod p;
    49               if (x=x0) and (y=y0) then
    50                  begin
    51                       l:=j;
    52                       break;
    53                  end;
    54          end;
    55      for i:=max(1,length(s2)-length(s1)+1) to length(s2) do
    56          begin
    57               j:=length(s2)-i+1;
    58               x:=(list[i-1,1]*a[j,1]) mod q;
    59               y:=(list[i-1,2]*a[j,2]) mod p;
    60               x0:=((b[length(s2),1]-b[i-1,1]) mod q+q) mod q;
    61               y0:=((b[length(s2),2]-b[i-1,2]) mod p+p) mod p;
    62               if (x=x0) and (y=y0) then
    63                  begin
    64                       l:=max(j,l);
    65                       break;
    66                  end;
    67          end;
    68      writeln(l);
    69      readln;
    70 end.     
  • 相关阅读:
    Git之常用的命令操作
    Linux之创建777权限的文件
    Mysql union
    读取MySQL数据表字段信息
    Linux下mysql启动失败
    TP5之使用layui分页样式
    使用Bootstrap实现表格列的显示与隐藏
    MySQL之避免插入重复数据
    Linux命令之清空当前文件
    opensns入门
  • 原文地址:https://www.cnblogs.com/HansBug/p/4418659.html
Copyright © 2011-2022 走看看