noip2002字串变换 2008.11.5
Program 1:滚动广搜
问题:1.2组的数组不够用
2.一定要自己造数据,在读题的时候,就要想到特殊数据,构造出来,在完成程序后,要先静态查错,多查几遍,然后,先测自己设计的边界数据,看是否符合,然后,要用f7,f8跟踪查错,确定每一步的变量值都正确,再测样例,也要单步跟踪,一定要先测自己的,再测样例。
3.像‘no answer’这类东西,一定要谨慎,把no answer的情况,全都试一遍,若halt,一定要在之前close
4.滚动光搜的缺点,不能用于记录下是否已经拓展过的状态
5.用滚动广搜时,变量千万不要带错。
program p_string;
const fin='string.in';fout='string.out';
var f1,f2:text;
x,y,z:string;
s:array[1..6,1..2]of string;
k:integer;
f:array[0..1,1..10000]of string;
l1,l2:array[0..1]of longint;
g:array[0..1,1..10000]of integer;
l:array[1..6,1..2]of byte;
procedure init;
var i,j,t:longint;
begin
k:=0;
assign(f1,fin);reset(f1);
assign(f2,fout);rewrite(f2);
readln(f1,z);
t:=pos(' ',z);
x:=copy(z,1,t-1);
y:=copy(z,t+1,length(z)-t);
{ writeln('---',x,'---');
writeln('---',y,'---');}
while not(eof(f1)) do
begin
readln(f1,z);
inc(k);
t:=pos(' ',z);
s[k,1]:=copy(z,1,t-1);
s[k,2]:=copy(z,t+1,length(z)-t);
l[k,1]:=length(s[k,1]);
l[k,2]:=length(s[k,2]);
{ writeln('---',s[k,1],'---');
writeln('---',s[k,2],'---');}
end;
fillchar(g,sizeof(g),0);
end;
procedure doit;
var p,c:string;now,i:byte;t:integer;
begin
l1[0]:=0;l2[0]:=1;f[0,1]:=x;now:=0;
repeat
l1[1-now]:=0;l2[1-now]:=0;
repeat
inc(l1[now]);
p:=f[now,l1[now]];
if g[now,l1[now]]>10 then begin writeln(f2,'NO ANSWER!');close(f1);close(f2);halt;end;
for i:=1 to k do
begin
t:=pos(s[i,1],p);
if t<>0 then
begin
inc(l2[1-now]);
g[1-now,l2[1-now]]:=g[now,l1[now]]+1;
f[1-now,l2[1-now]]:=copy(p,1,t-1)+s[i,2]+copy(p,t+l[i,1],length(p)-l[i,1]-t+1);
if (f[1-now,l2[1-now]]=y)and(g[1-now,l2[1-now]]<=10) then begin writeln(f2,g[1-now,l2[1-now]]);close(f1);close(f2);halt;end;
end;
end;
until l1[now]>=l2[now];
now:=1-now;
until l2[now]=0;
end;
begin
init;
doit;
writeln(f2,'NO ANSWER!');
close(f1);
close(f2);
end.
Pgoram 2:滚动广搜+双向搜索
1. 出现的问题:
(1) 第五组数据一直都不过,原来是生成的状态不够,如果,可以变换的单词,在串中出现了好多次,我刚开始只是对第一个出现的生成了状态,这样就损失了好多。
思维一定要谨慎!
(2) 判断重复时,对原来的串要进行替换(替换掉已经生成状态的那一位),替换时,必须再用一个string类型的变量储存下来经过多次变换的,否则,就影响字符串应有的形式了
2. 心得:如果有数据不过的话,一定要找出原因,找到源头,一定能有很多很深很强的感受,必须靠自己的力量ac,千万不能眼高手低,学习文化课也是一样。
当跟踪很麻烦时,可以打出运算过程中的值,与单步跟踪相结合。
program p_string;
const fin='string.in';fout='string.out';
var f1,f2:text;
x,y,z:string;
s:array[1..6,1..2]of string;
k:integer;
f,g:array[0..1,1..50000]of string;
l1,l2,m1,m2:array[0..1]of longint;
l:array[1..6,1..2]of byte;
procedure init;
var i,j,t:longint;
begin
k:=0;
assign(f1,fin);reset(f1);
assign(f2,fout);rewrite(f2);
readln(f1,z);
{ writeln(z);}
t:=pos(' ',z);
x:=copy(z,1,t-1);
y:=copy(z,t+1,length(z)-t);
{ writeln(x);
writeln(y);}
while not(eof(f1)) do
begin
readln(f1,z);
inc(k);
t:=pos(' ',z);
s[k,1]:=copy(z,1,t-1);
s[k,2]:=copy(z,t+1,length(z)-t);
l[k,1]:=length(s[k,1]);
l[k,2]:=length(s[k,2]);
{ writeln(s[k,1],' ',s[k,2]);}
end;
end;
function find(a1,a2:byte):boolean;
var i,j:longint;
begin
for i:=1 to l2[a1] do
for j:=1 to m2[a2] do
if f[a1,i]=g[a2,j] then exit(true);
find:=false;
end;
procedure print(x:byte);
begin
write(f2,x);
close(f1);close(f2);halt;
end;
procedure outf(h:byte);
var i:longint;
begin
writeln('tou:---------------');
for i:=1 to l2[h] do
write(f[h,i],' ');
writeln;
end;
procedure outg(h:byte);
var i:longint;
begin
writeln('wei:---------------');
for i:=1 to m2[h] do
write(g[h,i],' ');
writeln;
end;
procedure doit;
var p,c,pp:string;now,i,head,g1,f3:byte;t:integer;
begin
l1[0]:=0;l2[0]:=1;f[0,1]:=x;now:=0;
g1:=0;f3:=0;
m1[0]:=0;m2[0]:=1;g[0,1]:=y;head:=0;
repeat
if l2[now]<>0 then
begin
l1[1-now]:=0;l2[1-now]:=0;
inc(g1);if g1+f3>10 then begin writeln(f2,'NO ANSWER!');close(f1);close(f2);halt;end;
repeat
inc(l1[now]);
p:=f[now,l1[now]];
pp:=p;
for i:=1 to k do
begin
t:=pos(s[i,1],p);
while t<>0 do
begin
inc(l2[1-now]);
f[1-now,l2[1-now]]:=copy(p,1,t-1)+s[i,2]+copy(p,t+l[i,1],length(p)-l[i,1]-t+1);
if f[1-now,l2[1-now]]=y then print(g1);
pp:=copy(pp,1,t-1)+' '+copy(pp,t+1,length(pp)-t);//每次对他进行处理,而赋值时,用的是p
t:=pos(s[i,1],pp);
end;
end;
until l1[now]>=l2[now];
now:=1-now;
{ outf(now);}
end;
if find(now,head) then print(g1+f3);
if m2[head]<>0 then
begin
m1[1-head]:=0;m2[1-head]:=0;
inc(f3);if g1+f3>10 then begin writeln(f2,'NO ANSWER!');close(f1);close(f2);halt;end;
{ writeln('wei',f3);}
repeat
inc(m1[head]);
p:=g[head,m1[head]];pp:=p;
for i:=1 to k do
begin
t:=pos(s[i,2],p);
while t<>0 do
begin inc(m2[1-head]);
g[1-head,m2[1-head]]:=copy(p,1,t-1)+s[i,1]+copy(p,t+l[i,2],length(p)-l[i,2]-t+1);
pp:=copy(pp,1,t-1)+' '+copy(pp,t+1,length(pp)-t);
t:=pos(s[i,2],pp);
{ write(t,' ');}
end;//用于多个出现的判断
end;
until m1[head]>m2[head];
head:=1-head;
{ outg(head);}
end;
if find(now,head) then print(g1+f3);
until (l2[now]=0)and(m2[head]=0);
end;
begin
init;
doit;
writeln(f2,'NO ANSWER!');
close(f1);
close(f2);
end.