单词接龙(vijos1311)

本文详细探讨了搜索算法的关键细节,通过实例展示了如何优化算法,提高效率。文章以实际问题为背景,阐述了从字符串匹配到DFS搜索的全过程,特别强调了避免常见错误和优化策略。
算法:搜索

这道题花的时间不少,一言蔽之都是错在小的细节上了,因此对于这些细节一定要注意!
我们首先可以根据读入的字符串求出任意两个字符串之前的关系,用d[i,j]表示i字符串连接j字符串后新增加的长度,这里还要注意会出现自己连接自己的特殊情况。(错在这了半天的说)

然后就是简单的DFS了,注意每个字符串的使用次数是2,每个开头是关键字母的字符串都做一遍搜索即可。

program vijos1311;

const
 maxn=20;

var
 n,temlen,tot,ans:longint;
 s:array [0..maxn] of string;
 b:array [0..maxn,0..maxn] of boolean;
 d:array [0..maxn,0..maxn] of longint;
 len,v,start,vv:array [0..maxn] of longint;

procedure init;
var
 i,j,k,l:longint;
 t:boolean;
 x,y:string;
 ch:char;
begin
 ans:=0;
 tot:=0;
 readln(n);
 for i:=1 to n do 
  begin
   readln(s[i]);
   len[i]:=length(s[i]);
   v[i]:=2;
  end;
 vv:=v;
 readln(ch);
 for i:=1 to n do 
  begin
   if s[i,1]=ch then
    begin
     inc(tot);
     start[tot]:=i;
    end;
  end;
 for i:=1 to n do
  begin
   for j:=1 to n do 
    begin  
     t:=false;
     if len[i]>=len[j] then k:=len[j] else k:=len[i];
     if s[i]<>s[j] then
      begin
       for l:=1 to k do 
        begin
         x:=copy(s[i],len[i]-l+1,len[i]);
         y:=copy(s[j],1,l);
         if x=y then 
          begin
           t:=true;
           temlen:=l;
           break;
          end;
        end;
      end;
     if s[i]=s[j] then 
      begin
       for l:=1 to (len[i] shr 1) do
        begin
         x:=copy(s[i],1,l);
         y:=copy(s[j],len[j]-l+1,len[j]);
         if x=y then 
          begin
           t:=true;
           temlen:=l;
           break;         
          end;
        end;      
      end;
     if t then 
      begin
       b[i,j]:=true;
       d[i,j]:=len[j]-temlen;     
      end;
    end;
  end;
end;

procedure dfs(st,maxlen:longint);
var
 i:longint;
begin
 if maxlen>ans then ans:=maxlen;
 for i:=1 to n do 
  begin
   if (b[st,i]) and (v[i]>0) then
    begin
     dec(v[i]);
     dfs(i,maxlen+d[st,i]);
     inc(v[i]);
    end;
  end;
end;

procedure main;
var
 i:longint;
begin
 for i:=1 to tot do 
  begin
   v:=vv;
   v[start[i]]:=1;
   dfs(start[i],len[start[i]]);
  end;
end;

begin
 assign(input,'VJ1311.in'); reset(input);
 assign(output,'VJ1311.out'); rewrite(output);

 init;
 main;
 writeln(ans);

 close(input); close(output);
end.



评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值