洛谷P1019单词接龙(正向暴力递归+贪心)

题目链接:https://www.luogu.org/problemnew/show/P1019

 

这题就是搜索dfs遍历所有连接情况,找最大的。

难点在于:重合部分的处理,怎样获取这个重合长度。

 

另外,容易理解错的2点

1.一个字符开头,必定是包含的,所以要在主函数中for一个一个找哪个单词包含了它,字符不能放在搜索函数中(搜索函数考虑的就是不包含的情况!),不然没有答案。

2.关于重叠部分选取:

不是所有重合的都重合起来;

而是选最小的重合部分,单词接龙嘛,只要有一个字符尾首重合(即相同)就符合接龙的游戏规则,而且要求最长龙,必须选最小重合部分,这就是本题贪心规则。贪心没什么难的,就是容易理解错。

如:beaaa,aaas,重合长度为1不是3;baskask,askasklp重合长度为3不是6!

 

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <cstring>
 6 using namespace std;
 7 typedef long long ll;
 8 typedef unsigned long long ull;
 9 const int maxn=1e3+5;
10 const int inf=1e9;
11 string s[maxn],be;
12 int vis[maxn];//标记数组
13 int n,ans;
14 
15 int jud(string s1,string s2)//求最小重合长度函数,例子bask,asklp跟一遍就明白
16 {
17     int len1=s1.length(),len2=s2.length();
18     int f=0;
19     for (int i=1;i<min(len1,len2);i++)//注意:小于最短的本身减1!这就把包含情况去掉了!例如ask,askl就是0,非常巧妙!
20     {
21         f=0;
22         for(int j=0;j<i;j++)
23         {
24             if(s1[len1-i+j]!=s2[j]) { f=1; break; }
25         }
26 
27         if(!f) return i;//都没有变化,符合要求了返回最小重合
28     }
29 
30     return 0;
31 }
32 
33 
34 void so(string nowstr,int nowlen)
35 {
36     ans=max(ans,nowlen);//更新答案最长长度
37 
38     for(int i=1;i<=n;i++)
39     {
40         if(vis[i]>=2) continue;
41         int c=jud(nowstr,s[i]);//获取重合部分长度(因该是最小重合长度就行(因为有一个字符重合就能连接上!),多了不管)
42 
43         if(c>0) //有重叠部分就开始(包含部分已在jud函数中考虑到删去)
44         {
45             vis[i]++;
46             so(s[i],nowlen+s[i].length()-c);
47             vis[i]--;
48         }
49     }
50 }
51 
52 int main()
53 {
54     ios::sync_with_stdio(false); cin.tie(0);
55 
56     cin>>n;
57     for(int i=1;i<=n;i++) cin>>s[i];
58     cin>>be;
59 
60     for(int i=1;i<=n;i++)//第一个字符必包含,所以放在搜索函数外面
61     {
62         string st="";
63         st+=s[i][0];//因为字符s[i][0]不能直接和字符串be直接比较所以转换一下
64         if(st==be)
65         {
66             vis[i]++;
67             so(s[i],s[i].length());
68             vis[i]--;
69         }
70     }
71 
72     cout<<ans<<endl;
73 
74     return 0;
75 }

 

完。

posted @ 2018-10-05 18:28  RedBlack  阅读(283)  评论(0编辑  收藏  举报