洛谷 P1019单词接龙

看吧,多简单啊,没有人受伤的世界完成了。                                                                                            ——《我的青春恋爱物语果然有问题》

题目:https://www.luogu.org/problem/P1019

这一题是有点困难的字符串的深搜题,感觉好多题目一碰上字符串就变得麻烦不少。

可能是我太弱了

这题我的思路是这样的——

首先,先把每一次的接龙所得到的字符串存起来。

然后,每一次深搜,对于每个单词,看它能否接到原字符串后。

再然后,把字符串接上去,同时减少那个单词剩余可用次数。

最后,添上回溯。

我还要说一下那个包含问题:

其实包含不包含不重要,包含了跟不用它是一样的。

所以我就没有刻意去处理包含,也有可能是处理了我自己并没有意识到,望dalao指点

#include<bits/stdc++.h>
using namespace std;
int n,maxx=-1;
int a[25]={0};
char c;
char s[25][100],ans[500];
void dfs()
{
    int len=strlen(ans);
    for(int i=len-1;i>=0;i--)//从已经接好的单词(?)的末尾开始找 
    {
        for(int j=1;j<=n;j++)//遍历可以接上去的单词 
        {
            if(len-i>strlen(s[j])) continue;//优化,查单词会快得多 
            int flag=1;
            for(int k=0;k<len-i;k++)
              if(s[j][k]!=ans[i+k]) 
                flag=0;//看是否可以接上去 
            if(flag==1&&a[j]!=0)
            {
                int wyq=strlen(s[j]),wyc=len;
                for(int k=wyc-i;k<wyq;k++) ans[len++]=s[j][k];//会多加一个len值 
                a[j]--;//单词可用剩余次数少一次 
                if(maxx<len) maxx=len;
                dfs();
                for(int k=wyc-i-1;k<wyq;k++) ans[len--]=0;//删去加进去的单词
                //但会把最右边的位置多减一个 
                len++;//要加一补齐 
                a[j]++;//回溯 
            }
        }
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s[i]);
        a[i]=2;//保证每个单词只用两次 
    }
    cin>>c;
    ans[0]=c;
    dfs();
    printf("%d",maxx);
    return 0;
}
posted @ 2019-09-24 15:19  crxscp-173  阅读(126)  评论(0编辑  收藏  举报