比赛 暑假培训二 评测结果 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.