首页 > 代码库 > luogu 1019 单词接龙 dfs细节

luogu 1019 单词接龙 dfs细节

P1019 单词接龙

题目描述

单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at 和 atide 间不能相连。

输入输出格式

输入格式:

输入的第一行为一个单独的整数n (n<=20)表示单词数,以下n 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在.

输出格式:

只需输出以此字母开头的最长的“龙”的长度

输入输出样例

输入样例#1:
5attouchcheatchoosetacta
输出样例#1:
23           (连成的“龙”为atoucheatactactouchoose)   

说明

NOIp2000提高组第三题

 

Solution

比较水的一题,交了四五次才过,似乎药丸。。

首先compare一下计算出i 接 j 会延长多长记录在f[i,j]然后dfs瞎搞一下

题目比较迷,觉得自己的读题姿势有待提高

首先我们要弄清楚接龙到底是什么?
接龙?不就是普通的接龙吗?
不对,同个多次WA可以得知原来同样的两个串接龙可以有多种接法
比如ababab和ababcc,你可以接龙为abababcc或者ababababcc,所以我们可以在后面加一个优化

还有就是题目所说的包含关系,不包括自己接自己啊,
所以自己接自己,如果除了完全覆盖还有其他情况也可以

于是代码——

Codes

 1 program no; 2 uses math; 3 const 4   inf=test.in; 5   outf=test.out; 6 var 7    a:array[1..20] of string; 8    i,j,n,tot,ans:longint; 9    f:array[1..20,1..20] of longint;10    ex:array[1..20] of longint;11    tt:char;  12    13 procedure compare(aa,bb:longint);14 var15   i,j,lena,lenb,k:longint;16 begin17   lenb:=length(a[bb]);18   lena:=length(a[aa]);19   k:=maxlongint;20   for j:= lena downto 1 do21     if a[aa,j]=a[bb,1] then22      if copy(a[aa],j,lena-j+1)=copy(a[bb],1,lena-j+1) then23        if (lena-j+1=min(lena,lenb)) then  //如果有包含关系24             begin  if aa<>bb then exit; end //排除自己接自己25        else begin26               k:=min(k,lena-j+1);27               break;//优化28             end;29 30   if k<>maxlongint then31     f[aa,bb]:=lenb-k;//记录延长的长度32 end;33 34 procedure search(i:Longint);  //dfs35 var36   j:longint;37 begin38     for j:= 1 to n do39       if ex[j]>-2 then  //如果还有可以用的次数40         if f[i,j]<>0 then  //如果不是白接41         begin42           // writeln(i, ,j, ,f[i,j]);43             tot:=tot+f[i,j];44             dec(ex[j]);45             search(j);46             tot:=tot-f[i,j];47             inc(ex[j]);48         end;49     if ans<tot then ans:=tot;50 end;51 52 begin53     //assign(input,inf);  assign(output,outf);54     reset(input); rewrite(output);55 56     readln(n);57     for i:= 1 to n do58       readln(a[i]);59     for i:= 1 to n do60       for j:= 1 to n do61         compare(i,j);62     readln(tt);63     for i:= 1 to n do    //枚举开头的串64       if tt=a[i,1] then65       begin66         fillchar(ex,sizeof(ex),0);67         tot:=length(a[i]);68         dec(ex[i]);69         search(i);70       end;71     writeln(ans);72     close(input);  close(output);73 end.

 

luogu 1019 单词接龙 dfs细节