noip2002字串变换 2008.11.5

noip2002字串变换 2008.11.5

Program 1:滚动广搜

问题:1.2组的数组不够用

2.一定要自己造数据,在读题的时候,就要想到特殊数据,构造出来,在完成程序后,要先静态查错,多查几遍,然后,先测自己设计的边界数据,看是否符合,然后,要用f7f8跟踪查错,确定每一步的变量值都正确,再测样例,也要单步跟踪,一定要先测自己的,再测样例。

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.



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值