1
已采纳
梁锦程
高级光能
高级光能
此题乍一看,似乎并不是很难,但需要处理以下一些情况:
1.单词不能包含。
2.每个单词可以用2次。
3.重合部分长度需减去。
4.重合长度是不确定的。
现在谈谈大体思路:
首先此题一定用深搜。
其次存单词时,从f[1]开始存,而最后一个表示开头的字母存f[0]。
why?我们接龙时就直接从f[0]开始便不需要处理开头的单词。
接下来处理问题:
1.关于包含,只需查到长度len-1即可,如果还不符合便不符合。
2.我们可以定义一个v数组,判断单词使用次数,在使用前判断if(v[i]<2)每使用一次变v[i]++,注意递归完后v[i]--。
然后先看4.在判断单词是否可以连接时,我们从i=0,循环到i=n,即所有单词查完,如果单词可用便接着循环,查待连接单词,如果某一位与可连接单词相同,便再循环,定义一个临时变量t,从后一位开始,查,如果不同,直接t=0,break,出循环后if(t)便代表可连接,开始递归下一个,别忘了v[i]++。(此部分便是核心算法)
关于3.在判断可连接时,总长度L便加上两个单词长度,然后前面的最后盘点是否完全符合的循环计数变量定义在外面,L直接减去它便是接龙长度了。
不知道是否听懂……
直接上主程序:
void jl(int x,int len)//两个参数分别代表待连接单词的结构体下标和长度
{
for(int i=1;i<=n;i++)
if(c[i].v<2)//判断访问次数
for(int j=0;j<c[x].len;j++)//查待连接单词的每一个字母
if(c[x].s[j]==c[i].s[0])
{
int k=1;//将循环变量定义在外面,方便以后相减
int t=1;//临时变量(其实bool就行)
for(int l=j+1;l<c[x].len&&k<c[i].len;k++,l++)//l表示待连接单词下标,k是可连接单词下标,所以在循环条件中需满足它们小于(因为不能包含,所以不能等于)单词长度
if(c[x].s[l]!=c[i].s[k])
{
t=0;
break;
}
if(t)
{
c[i].v++;
jl(i,len+c[i].len-k);//更新长度和下标后递归
c[i].v--;//完成后一定记得--
}
}
if(len>maxn)
maxn=len;//不解释
}
1
0
0
0
0