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.
=====================