题目描述 Description
已知有两个字串 A$, B$ 及一组字串变换的规则(至多6个规则):
A1$ -> B1$
A2$ -> B2$
规则的含义为:在 A$中的子串 A1$ 可以变换为 B1$、A2$ 可以变换为 B2$ …。
例如:A$='abcd' B$='xyz'
变换规则为:
‘abc’->‘xu’ ‘ud’->‘y’ ‘y’->‘yz’
则此时,A$ 可以经过一系列的变换变为 B$,其变换的过程为:
‘abcd’->‘xud’->‘xy’->‘xyz’
共进行了三次变换,使得 A$ 变换为B$。
输入描述 Input Description
输入格式如下:
A$ B$
A1$ B1$ \
A2$ B2$ |-> 变换规则
... ... /
所有字符串长度的上限为 20。
输出描述 Output Description
若在 10 步(包含 10步)以内能将 A$ 变换为 B$ ,则输出最少的变换步数;否则输出"NO ANSWER!"
样例输入 Sample Input
abcd xyz
abc xu
ud y
y yz
样例输出 Sample Output
3
题解:BFS+hash判重
const
maxp=100007;
maxn=1000000;
type
node=record
dep:longint;
data:string;
end;
var
st1,st2,st:string;
n,i,x,min:longint;
s:array[1..2,0..100] of string;
p:array[0..maxn] of node;
hash:array[0..maxp] of boolean;
function check(s:string):boolean;
var k:int64;
begin
k:=0;
for i:=1 to length(s) do
k:=(k*100+ord(s[i]))mod 65537;
if hash[k] then
begin
hash[k]:=false;
exit(true);
end
else exit(false);
end;
procedure bfs;
var
head,tail,i:longint; st1:string;
begin
head:=1;
tail:=2;
p[head].data:=st1;
p[head].dep:=0;
while head<tail do
begin
if (p[head].dep>=10)or(p[head].dep>=min) then
begin
inc(head);
continue;
end;
if p[head].data=st2 then
begin
if p[head].dep<min then min:=p[head].dep;
inc(head);
continue;
end;
for i:=1 to n do
begin
x:=pos(s[1,i],p[head].data);
st:=p[head].data;
while x>0 do
begin
st[x]:='#';
st1:=p[head].data;
delete(st1,pos(s[1,i],p[head].data),length(s[1,i]));
insert(s[2,i],st1,x);
if check(st1) then
begin
p[tail].data:=st1;
p[tail].dep:=p[head].dep+1;
inc(tail);
end;
x:=pos(s[1,i],st);
end;
end;
inc(head);
end;
end;
begin
fillchar(hash,sizeof(hash),true);
n:=0;
readln(st);
x:=pos(' ',st);
st1:=copy(st,1,x-1);
st2:=copy(st,x+1,length(st)-x);
while not eof do
begin
inc(n);
readln(st);
x:=pos(' ',st);
s[1,n]:=copy(st,1,x-1);
s[2,n]:=copy(st,x+1,length(st)-x);
end;
min:=maxlongint;
bfs;
if min=maxlongint then writeln('NO ANSWER!') else writeln(min);
end.