比赛 |
暑假培训二 |
评测结果 |
AAAAWAWT |
题目名称 |
字串变换 |
最终得分 |
62 |
用户昵称 |
BYVoid |
运行时间 |
0.000 s |
代码语言 |
Pascal |
内存使用 |
0.00 MiB |
提交时间 |
2008-07-18 09:02:18 |
显示代码纯文本
program noipg2;{一个未加剪枝的朴素双向bfs}
type
stringtype=string;
var
queuez,queuef:array[1..10000] of stringtype;{正反向队列}
rule:array[1..60,1..20] of stringtype;{转换规则}
countz,countf:array[1..10000] of integer;{答案计数}
start,goal:stringtype;{ 初始状态和目标状态}
hz,hf,tz,tf,rp:integer;{两个队列指针}
procedure init;{输入初始以及目标,还有规则}
var
i,p,j:integer;
s:stringtype;
begin
assign(input,'string.in');reset(input);
assign(output,'string.out');rewrite(output);
readln(s);{读入字符串}
p:=pos(' ',s);
start:=copy(s,1,p-1);
goal:=copy(s,p+1,length(s));{空格前面为初始后面为目标}
i:=0;
while not eof do{读入规则}
{for j:=1 to 6 do}
begin
inc(i);
readln(s);
p:=pos(' ',s);
rule[i,1]:=copy(s,1,p-1);
rule[i,2]:=copy(s,p+1,length(s));
end;
rp:=i;{规则的总数}
hz:=1;hf:=1;tz:=1;tf:=1;{正反队列的头尾指针赋初值}
queuez[1]:=start;{正向队列加入初始状态}
queuef[1]:=goal;{反向队列加入木标状态}
countf[1]:=0;countz[1]:=0;{转换次数计数}
end;
procedure reverse1(x:integer;t:boolean; {转换是否成功}var temp:stringtype);{正向搜索转换方式}
var
i:integer;
begin
t:=false;
for i:=1 to length(temp)-length(rule[x,1])+1 do{枚举是否匹配}
begin
if copy(temp,i,length(rule[x,1]))=rule[x,1] then
begin
t:=true;
delete(temp,i,length(rule[x,1]));{转换}
insert(rule[x,2],temp,i);
exit;
end;
end;
end;
procedure reverse2(x:integer;t:boolean; {转换是否成功}var temp:stringtype);{反向搜索转换方式}
var
i:integer;
begin
t:=false;
for i:=1 to length(temp)-length(rule[x,2])+1 do{枚举是否匹配}
begin
if copy(temp,i,length(rule[x,2]))=rule[x,2] then
begin
t:=true;
delete(temp,i,length(rule[x,2]));{转换}
insert(rule[x,1],temp,i);
exit;
end;
end;
end;
procedure dbfs;{双向bfs}
var
i,j:integer;
temp:stringtype;
t,visited:boolean;
begin
while (tf>=hf)or(tz>=hz) do
begin
for i:=1 to 6 do{枚举每种转换规则}
begin
temp:=queuez[hz];
reverse1(i,t,temp);{试图以规则i转换temp,t记录转换是否成功}
if t then
begin
for j:=1 to tf do{是否在逆向搜索队列中出现}
if temp=queuef[j] then
begin
writeln(countz[hz]+1+countf[j]);{输出解}
exit;
end;
visited:=false;
for j:=1 to tz do{是在同向队列重复出现}
if temp=queuez[j] then
begin
visited:=true;
break;
end;
if not visited then begin{若没出现则加入队列}
inc(tz);
queuez[tz]:=temp;
countz[tz]:=countz[hz]+1;
if countz[tz]> 10 then
begin
writeln('NO ANSWER!');{>10步,无解}
exit;
end;
end;
end;
end;
inc(hz);
{==================逆向搜索,过程略同==================}
for i:=1 to 6 do
begin
temp:=queuef[hf];
reverse2(i,t,temp);
if t then
begin
for j:=1 to tf do
if temp=queuez[j] then
begin
writeln(countf[hf]+1+countz[j]);
exit;
end;
visited:=false;
for j:=1 to tf do
if temp=queuef[j] then
begin
visited:=true;
break;
end;
if not visited then begin
inc(tf);
queuef[tf]:=temp;
countf[tf]:=countf[hf]+1;
if countf[tf]> 10 then
begin
writeln('NO ANSWER!');
exit;
end;
end;
end;
end;
inc(hf);
end;
writeln('NO ANSWER!');{无解}
end;
begin
init;
dbfs;
close(input);
close(output);
end.