(╥╯^╰╥)说起这道题就心酸,几个数据特别坑,几分钟写完的程序花了一个上午调试bug,吐槽完毕,进入正题:
1,需要建立一个标记数组vis表示当前单词被采取的次数;
2,for循环中找到每一个符合条件的龙头,初始化标记数组后进行深度优先搜索;
3,因为连接起来的单词要最长,所以对比是选择从上一个单词的末尾与当前单词的开头进行比对,一旦符合就return
注意!字符相等还不一定符合题意,一定要比到上一个单词的最后一个字符才算符合条件,给出两组数据自己揣摩:
(自己思考后才能有收获吗(~ ̄▽ ̄)~ )
1 2
envelope abababab
e abababc
ans:15 a ans:19下面在代码中进行分析:
#include#include #include using namespace std;struct node{ char lin[1000];}s[20]; // 结构体 s 用于储存单词 int t,ans;int vis[20]; //标记数组,每一次搜索初始化为 0,单词使用一次加一,超过二就不能继续使用 int len[20]; //单词长度数组,表示每一个单词的长度 int found(int stp,int i){ //stp代表上一个已经选择的单词下标 i表示当前的单词下标 int q,w,j; for(q=len[stp]-1;q>=1;q--){ //为使长度最长,从上一个单词的末尾开始搜索 if(s[stp].lin[q]==s[i].lin[0]){ //第一个字符匹配后继续看后面还有多少位 int x=0; //相同位数 for(w=q,j=0;w =2)continue;//单词已经被找过两次,跳过 int x=found(stp,i); //x代表上一个单词与当前单词的匹配位数 if(x!=0){ //匹配位数不为0就继续进行下一次的单词搜索 mark=true; length+=(len[i]-x); //当前长度增加 vis[i]+=1; //当期单词用过一个加一 dfs(i,length); //上一步递归不符合题意返回至此,长度减去不符合题意的单词,单词的使用次数减一,继续选择单词 length-=(len[i]-x); vis[i]-=1; } } if(mark==false){ //如果已经找不到单词,比较之前已经得到过的答案选择最长的单词数 ans=max(ans,length); }}int main(){ int i; char l1; cin>>t; for(i=0;i >s[i].lin; len[i]=strlen(s[i].lin); } cin>>l1; ans=0; for(i=0;i