题目
易错点
思维盲区(也是对dfs的不熟悉)
在dfs中,比如有多个可能都可以符合当前递归的要求,那就把所有范围都遍历一遍,用if作为条件判断,如果成立,在真正地进行递归
也就是在dfs里出现for循环,依次遍历每个可能的方案,并用if进行条件筛选
不用担心不成立怎么办,因为代码的写法会让不成立的逐个扫描过去,如果无路可走,就会直接回溯
本题中有两处地方都是这样的:
1、对于当前字符串x后所要连接的字符串,所有字符串s[i]都有可能,那就对所有字符串s进行遍历。再用if进行判断
2、刚开始第一次调用dfs时,只要是首字母和所给出的字母一样的,都可能作为首单词,因此遍历所有的字符串,只要能作为首单词,就进行深度搜索
3、最大值就是在多种可能的深搜中,一次次取max得到所有情况里的最大值
总结:
深搜的本质依旧是搜索,所以遍历所有可能情况是再正常不过的事情。
特殊就特殊在是“深”,因为一旦当前某种选择成立了,我们就在这之下继续调用dfs搜索下去。
对“相邻的两部分不能存在包含关系”的错误思考
因此要保证不会出现这两种情况
只需让j<x.size()&&j<s[i].size()
如何判断字符串A和字符串B能否相接
从小到大枚举相同部分的长度,一旦找到相等的,就break。因为这时候就是最小的公共前后长度,取最小的,能保证连出来的是最长的
使用substr取出子串,然后判断是否相等
int len=x.size();
for(int j=1;j<x.size()&&j<s[i].size();j++){
if(x.substr(x.size()-j,j)==s[i].substr(0,j)){
len=j;
break;//从小到大,找到相等的。这时候就是最小的公共前后长度,取最小的,能保证连出来的是最长的
}
}
if(len<x.size()&&len<s[i].size()){
//说明两个串没有重合且拥有前后相等部分,能选
t+=s[i].size()-len;
use[i]++;
dfs(s[i]);
t-=s[i].size()-len;
use[i]--;
}
没有初始化导致的严重错误
一开始我写的是int len;
没有初始化
导致多次运行同一样例,竟然出现了不同的结果
如果没给len初始化时赋值,会导致如果下面for没成立,len的值就一直等于随机值,造成后文对len的判断错误!!!!
什么东西必须记录,什么东西没必要记录要弄清楚
比如本题最后要输出的就是一个最大长度
那根本没必要存下来整个穿在一起的字符串
直接存当前已经串出来的长度就好了
#include <bits/stdc++.h>
using namespace std;
const int N=25;
int n;
string s[N];
int use[N];
int t;//每次当前已经连接的字符串长度,只记下长度,不记总的连的字符串的内容
int ans;
void dfs(string x)
{
ans=max(ans,t);//先对ans和当前长度t取个最大值
//找出能连在x后面的(只要能连,就遍历,反正有max取最大值)
for(int i=0;i<n;i++){
if(use[i]<2){
int len=x.size();//我这里一开始没给len赋值,导致如果下面for没成立,len的值就一直等于随机值,造成后文对len的判断错误!!!!
for(int j=1;j<x.size()&&j<s[i].size();j++){
if(x.substr(x.size()-j,j)==s[i].substr(0,j)){
len=j;
break;//从小到大,找到相等的。这时候就是最小的公共前后长度,取最小的,能保证连出来的是最长的
}
}
if(len<x.size()&&len<s[i].size()){
//说明两个串没有重合且拥有前后相等部分,能选
t+=s[i].size()-len;
use[i]++;
dfs(s[i]);
t-=s[i].size()-len;
use[i]--;
}
}
}
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++) cin>>s[i];
//易错点
//不要用 scanf("%c",...) 很容易错! 因为会读取换行符,空格符等
//char beg;scanf("%c",&beg);
char beg[2];scanf("%s",beg);//改成使用scanf("%s",...)输入到char数组,然后使用char[0]
for(int i=0;i<n;i++){//每个符合要求的字符串都试试作为起始串
if(s[i][0]==beg[0]){
use[i]++;
t=s[i].size();
dfs(s[i]);
use[i]--;
}
}
printf("%d\n",ans);
return 0;
}