首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >洛谷 P1019 单词接龙

洛谷 P1019 单词接龙

作者头像
glm233
发布2020-09-28 11:16:13
5720
发布2020-09-28 11:16:13
举报

题目链接

题目描述

单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at和 atide间不能相连。

这道题需要注意三点:

1.每个单词最多在龙里出现两次

2.不能在龙里出现包含关系

3.可以有重合部分

很明显,第一个要接的单词必须首字母是给出的字母,dfs的入口就是满足这个条件的字符串,答案就是这些字符串去dfs找出的最大值,如何dfs?接下来的单词前一部分必须是上一个已经在龙里面的单词的某个后缀,那就去遍历上一个单词从尾开始找,找到一个字符和要接的单词的开头一样,ok接着找,其中一旦发现有某个字符不一样那就不能接龙,如果都可以就返回新增的长度,不如auto,utoh,随便举个例子,找到一个字符和要接的单词一样的位置是u,新增长度是要接的字符长度减去公共长度4-3=1~

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rg register ll
string s[25];
ll ans,maxx,vis[25],n;
inline ll com(ll x,ll y)
{
    for(rg i=s[x].length()-1;i>=1;i--)
    {
        if(s[x][i]==s[y][0])
        {
            ll ans=0;
            for(rg j=i+1;j<=s[x].length()-1;j++)
            {
                if(s[x][j]!=s[y][++ans])return 0;
            }
            return s[y].length()-ans-1;
        }
    }
    return 0;
}
inline void dfs(ll x)
{
    for(rg i=1;i<=n;i++)
    {
        if(vis[i]<2&&com(x,i))
        {
            ans+=com(x,i);
            vis[i]++;
            dfs(i);//回溯
            vis[i]--;
            ans-=com(x,i);
        }
    }
    //cout<<ans<<endl;
    maxx=max(maxx,ans);
}
int main()
{
    cin>>n;
    for(rg i=1;i<=n;i++)cin>>s[i];
    getchar();
    char ch;
    cin>>ch;
    for(rg i=1;i<=n;i++)
    {
        if(s[i][0]==ch)
        {
            ans=s[i].length();
            vis[i]++;
            dfs(i);
            vis[i]--;
            maxx=max(maxx,ans);
            //cout<<maxx<<endl;
        }
    }
    cout<<maxx<<endl;
    //while(1)getchar();
    return 0;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-02-02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 这道题需要注意三点:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档