• 解题报告 语文


    1、 诗歌的主题(chinese)

    问题描述

    众所舟舟知,zsz童鞋是语文课代表,此人ws至极,仗着职权之便,从来不交语文积累本,终于有一天,他被老班发现了(乌卡卡卡卡卡)。于是老班给他出了一个特别的诗歌鉴赏题:

    为了方便描述,我们将诗歌中的字用数字代表,现在zsz要找出诗歌中长度最长的一个主题。

    诗歌的主题要满足以下几个要求:

    1、 它是整首诗歌的一个字串

    2、 长度至少为5

    3、 在诗歌中必须重复出现(可能经过诗人的加工,加工方法见下文)

    4、 重复出现的同一主题不能有公共部分

    加工的意思是主题序列中的每个数字,都被加上或减去了同一个整数。给定一首诗歌,计算其中最长的主题长度。

    输入格式

    第一行一个整数n,表示诗歌的长度

    下面的每一行包含20个整数,表示诗歌的内容,最后一行的数的个数可能小于n,总之,一共n个整数。

    输出格式

    一个整数,即最长的主题长度。如果找不到符合要求的主题,输出0

    样例输入

    30

    25 27 30 34 39 45 52 60 69 79 69 60 52 45 39 34 30 26 22 18

    82 78 74 70 66 67 64 60 65 80

    样例输出

    5

    数据范围

    1<=n<=5000

    1<=ai(每个数字)<=100

     

    Liukeke 的学科试题之四·语文。

     

    首先,我们将相邻的两项对减,也就是求出它的每两项的差来,这样就相当于把那个“加工”去掉了。----------------我考试的时候就是因为这个 WA 的,%>_<%

     

    然后就好办了,枚举+二分,水过。

    不过要注意,这样求出来的长度是这个序列的“差”数,也就是间隔数,需要 +1 

    代码(SueMiller

    program ACRush;

     

    var a,b:array[0..5001]of integer;

        i,j,k,n:integer;

        ans:integer;

        l,r,m:integer;

     

    function same(x,y,q:integer):boolean;

    var i:integer;

    begin

      for i:=1 to q do

        if b[x-1+i]<>b[y-1+i] then exit(false);

      exit(true);

    end;

     

    function check(x:integer):boolean;

    var i,j:integer;

    begin

      for i:=n-x-x+1 downto 1 do

        for j:=i+x to n-x+1 do

          if same(i,j,x) then exit(true);

     

      exit(false);

    end;

     

    begin

      assign(input,'chinese.in');reset(input);

      assign(output,'chinese.out');rewrite(output);

     

      readln(n);

      read(a[0]);

      for i:=1 to n-1 do

        begin

          read(a[i]);

          b[i]:=a[i]-a[i-1];

        end;

      dec(n);

     

      l:=5;

      r:=n>>1;

      m:=(l+r)>>1;

      while r-l>2 do

        begin

          if check(m) then

            begin

              l:=m;

              m:=(l+r)>>1;

            end

          else begin

            r:=m;

            m:=(l+r)>>1;

          end;

        end;

     

      if check(r) then writeln(r+1)

      else

        if check(m) then writeln(m+1)

    else if check(l) then writeln(l+1)

        Else writeln(0); 

     

      close(input);close(output);

    End.

     

     

     

    然后,还有一种比较好的枚举:枚举 ,然后直接判断间隔为 的两个数字是否相同,相同的话记录的长度加一,不同的话更新 ans 

    其实这个方法我也不太明白。。。。。。。。。

     

    代码(Liukeke

    program liukeke;

    var

      a,b:array[0..5001] of longint;

      i,n,ans,num,l:longint;

     

    begin

      assign(input,'chinese.in');reset(input);

      assign(output,'chinese.out');rewrite(output);

      readln(n);

      for i:=1 to n do

        read(a[i]);

      for i:=1 to n-1 do

        b[i]:=a[i+1]-a[i];

      ans:=0;

      num:=1;

      dec(n);

      for l:=5 to n-1 do

      begin

        if num>ans then ans:=num;

        num:=1;

        for i:=1 to n-l do

          if (b[i]=b[i+l])and(num+1<=l) then

            inc(num)

          else

          begin

            if num>ans then ans:=num;

            num:=1;

          end;

      end;

      if ans>=5 then

        writeln(ans)

      else writeln(0);

      close(input);

      close(output);

    end.

     

     

  • 相关阅读:
    不使用border-radius,实现一个可复用的高度和宽度都自适应的圆角矩形
    实现一个div在浏览器水平居中
    HTML画布(2)
    《10X工作法制》笔记
    消息体的上传格式
    在rpc链路中的工作总结
    同属姓名注入spring报错
    《事实》听后感
    jdk8使用stream对指定值去重以及其他stream用法
    如何写好业务(待续)
  • 原文地址:https://www.cnblogs.com/SueMiller/p/2223976.html
Copyright © 2020-2023  润新知