这道题目可以用动态规划解决,为了方便起见用了记忆化搜索。在代码中,我把所有的字符全都转换成了数字便于后面的操作。不知道哪里写逗了结果跑得这么慢。。
程序中用f[u][v][k]表示u..v这一段能否用编号为k的字母表示。-1表示尚未计算,0表示不行,1表示可以。具体的转移方程见代码。
下附AC代码:
const
n=4;
ans:array[1..4] of char=('W','I','N','G');
var
c:array['A'..'Z'] of longint;
p,q:array[0..n,0..20] of longint;
a:array[0..n] of longint;
b:array[0..210] of longint;
f:array[0..210,0..210,0..4] of longint;
i,j,len:longint; bo:boolean;
ch1,ch2:char; s:string;
function dp(u,v,k:longint):longint;
var
x,i:longint;
begin
if f[u][v][k]<>-1 then exit(f[u][v][k]);
if u=v then
begin
if b[u]=k then f[u][v][k]:=1
else f[u][v][k]:=0;
exit(f[u][v][k]);
end;
for x:=1 to a[k] do
for i:=u to v-1 do
if dp(u,i,p[k][x])+dp(i+1,v,q[k][x])=2 then
begin
f[u][v][k]:=1; exit(1);
end;
f[u][v][k]:=0;
exit(0);
end;
begin
fillchar(f,sizeof(f),255);
c['W']:=1; c['I']:=2; c['N']:=3; c['G']:=4;
for i:=1 to n do read(a[i]); readln;
for i:=1 to n do
for j:=1 to a[i] do
begin
readln(ch1,ch2);
p[i][j]:=c[ch1]; q[i][j]:=c[ch2];
end;
readln(s); len:=length(s);
for i:=1 to len do b[i]:=c[s[i]];
bo:=true;
for i:=1 to n do
if dp(1,len,i)=1 then
begin
bo:=false; write(ans[i]);
end;
if bo then writeln('The name is wrong!');
end.
2015.2.8
by lych