Calf Flac最长的回文

 Calf Flac最长的回文
据说如果你给无限只母牛和无限台巨型便携式电脑(有非常大的键盘),那么母牛们会制造出世上最
棒的回文.
你的工作就是去这些牛制造的奇观中寻找最长的回文.
寻找回文时不用理睬那些标点符号、空格(但应该保留下来以便做为答案输出),只用考虑字母
'A'-'Z'和'a'-'z'.
要你寻找的最长的回文的文章是一个不超过 20,000 个字符的字符串.
我们将保证最长的回文不会超过 2,000 个字符(在除去标点符号、空格之前).
PROGRAM NAME: calfflac
INPUT FORMAT
一个不超过 20,000 个字符的文件.
SAMPLE INPUT (file calfflac.in) 
Confucius say: Madam, I'm Adam.
OUTPUT FORMAT
输出的第一行应该包括找到的最长的回文的长度.
下一个行或几行应该包括这个回文的原文(没有除去标点符号、空格),
把这个回文输出到一行或多行(如果回文中包括换行符).
如果有多个回文长度都等于最大值,输出那个前出现的.
SAMPLE OUTPUT (file calfflac.out)
11
Madam, I'm Adam

=====================

提供两种思路..

1.枚举起点..枚举末尾点...(最后一组要超时)...  [见代码1]

2.枚举中点,向两边扩展。[见代码2].

------------------------------------------------------

分析思路1超时原因..

枚举了许多无效节点....比如说st[i,j]...你不确定中间的就保证是回文...

而思路2..

每一步枚举的都是有效的...

如果st[mid-1]<>st[mid+1]则后面就不会枚举了...

---------------------------------------

[代码1]

{
ID:jie19952
PROG:calfflac
LANG:PASCAL
}
type
  re=record
       ch:char;
       num:longint;
     end;
var
  st:ansistring;
  a:array[1..20000]of re;
  n:longint;
  ans_l,ans_r,ans_len:longint;
  
procedure init;
begin
  assign(input,'calfflac.in');
  //assign(output,'calfflac.out');
  reset(input);// rewrite(output);
end;

procedure terminate;
begin
  close(input); //close(output);
  halt;
end;

function min(a,b:longint):longint;
begin
  if a>b then exit(b);
  exit(a);
end;

function check(l,r:longint):boolean;
var
  i:longint;
begin
  check:=true;
  for i:=l to (l+r) shr 1 do
    begin
     // writeln(a[i].ch,' ',a[r-i+l].ch,' ',l,' ',r);
      if a[i].ch<>a[r-i+l].ch then exit(false);
    end;
end;

procedure main;
var
  i,j:longint;
  ch:char;
begin
  n:=0;
  //writeln(ord('a'));
  //writeln(ord('A'));
  ans_len:=1;
  ans_l:=1;
  ans_r:=1;
  st:='';
  while not eof do
    begin
      read(ch);
      st:=st+ch;
    end;


  for i:=1 to length(st) do
    begin
      if st[i] in ['A'..'Z'] then
        begin
          inc(n);
          a[n].ch:=char(ord(st[i])+32);
          a[n].num:=i;
        end;
      if st[i] in ['a'..'z'] then
        begin
          inc(n);
          a[n].ch:=st[i];
          a[n].num:=i;
        end;
    end;
  //for i:=1 to n do
    //write(a[i].ch);
  //writeln;
  for i:=1 to n do
    begin
      for j:=i+min(n,2000)-1 downto i+ans_len do
        begin
          if check(i,j) then
            begin
              ans_l:=i;
              ans_r:=j;
              ans_len:=j-i+1;
              break;
             // if ans_len=2000 then
               // begin
                 // writeln(ans_len);
                  //terminate;
               // end;
            end;
        end;
    end;
  writeln(ans_len);
  for i:=a[ans_l].num to a[ans_r].num do
    begin
      write(st[i]);
    end;
  writeln;
end;

begin
  init;
  main;
  terminate;
end.


 

[代码2]

{
ID:jie19952
PROG:calfflac
LANG:PASCAL
}
type
  re=record
       ch:char;
       num:longint;
     end;
var
  st:ansistring;
  a:array[1..20000]of re;
  n:longint;
  ans_l,ans_r,ans_len,len:longint;

procedure init;
begin
  assign(input,'calfflac.in');
  assign(output,'calfflac.out');
  reset(input); rewrite(output);
end;

procedure terminate;
begin
  close(input); close(output);
  halt;
end;

function min(a,b:longint):longint;
begin
  if a>b then exit(b);
  exit(a);
end;

function check1(mid:longint;var l,r:longint):longint;
begin
  check1:=1;
  l:=mid-1; r:=mid+1;

  while (l>=1)and(r<=len)and(a[l].ch=a[r].ch) do
    begin
      dec(l); inc(r);
      inc(check1,2);
    end;
  if a[l].ch<>a[r].ch then
    begin
      inc(l); dec(r);
    end;
end;

function check2(mid:longint;var l,r:longint):longint;
begin
  check2:=0;
  l:=mid; r:=mid+1;

  while (l>=1)and(r<=len)and(a[l].ch=a[r].ch) do
    begin
      dec(l); inc(r);
      inc(check2,2);
    end;
  if a[l].ch<>a[r].ch then
    begin
      inc(l); dec(r);
    end;
end;

procedure main;
var
  i,j,t:longint;
  l,r:longint;
  ch:char;
begin
  n:=0;
  //writeln(ord('a'));
  //writeln(ord('A'));
  ans_len:=1;
  ans_l:=1;
  ans_r:=1;
  st:='';
  while not eof do
    begin
      read(ch);
      st:=st+ch;
    end;

  len:=length(st);
  for i:=1 to len do
    begin
      if st[i] in ['A'..'Z'] then
        begin
          inc(n);
          a[n].ch:=char(ord(st[i])+32);
          a[n].num:=i;
        end;
      if st[i] in ['a'..'z'] then
        begin
          inc(n);
          a[n].ch:=st[i];
          a[n].num:=i;
        end;
    end;
  //for i:=1 to n do
    //write(a[i].ch);
  //writeln;
  for i:=1 to n do
    begin
      t:=check1(i,l,r);
      if t>ans_len then
        begin
          ans_l:=l;
          ans_r:=r;
          ans_len:=t;
        end;
      t:=check2(i,l,r);
      if t>ans_len then
        begin
          ans_l:=l;
          ans_r:=r;
          ans_len:=t;
        end;
    end;
  writeln(ans_len);
  for i:=a[ans_l].num to a[ans_r].num do
    begin
      write(st[i]);
    end;
  writeln;
end;

begin
  init;
  main;
  terminate;
end.


 

=====================

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值