zoukankan      html  css  js  c++  java
  • 洛谷 p1019 单词接龙

    题目描述

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

    输入输出格式

    输入格式:

    输入的第一行为一个单独的整数n(n≤20)表示单词数,以下n 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在.

    输出格式:

    只需输出以此字母开头的最长的“龙”的长度

    分析

    本题还是一道dfs问题 重要的是如何处理给出的单词 以及如何构建一个dfs

    首先我们注意到,想要找到最长的“龙”,根据贪心的原则,重合部分要取最小 比如 asdd 和ddas 这两个“单词”,合起来就是adddas 也就是只重合一个字母 而不是asddas 这一点是需要注意的

    首先为了dfs的方便 我们可以构造一个数组 p[i][j] 代表 i 单词在前 j 单词在后的时候会重合多少字母 还是asdd和ddas的例子 如果i 单词是asdd,j 单词是ddas 那么p[i][j]=1,p[j][i]=2

    至于构造的方式 看下面的代码就好了 注意一定是最小的重合部分。

    代码:

    #include<bits/stdc++.h>
    
    using namespace std;
    
    string s[30];
    char d;
    int n,vis[21],p[30][30],ans=-1,an=0;
    
    void ff(int x,int y)
    {
        int k,kx;
        int ky=0;
        int flag=1;
        for(k=s[x].size()-1;k>=0;k--)
        {
        for(kx=k;kx<=s[x].size()-1;kx++)
        {
            if(s[x][kx]!=s[y][ky++]) 
            {
                flag=0;
                break;
            }
        }
        if(flag) //只要有重合部分就跳出,这样保证了重合的是最小的
        {
            p[x][y]=s[x].size()-k;
            return;
        }
        ky=0;
        flag=1;
        }
        return ;
    }
    
    
    void dfs(int x)
    {
        int i,flag=0;
        for(i=0;i<n;i++)
        if(vis[i]<2&&p[x][i]!=0&&s[x].size()!=p[x][i]&&s[i].size()!=p[x][i])
        {
            flag=1;
            an+=s[i].size()-p[x][i];
            vis[i]++;
            dfs(i);
            vis[i]--;
            an-=s[i].size()-p[x][i];
        }
        if(!flag)  //如果没有新的单词可以“接龙”,判断是否是更长的“龙”并返回
        ans=max(ans,an);
        return;
    }
    
    int main()
    {
        int i,j;
        cin>>n;
        for(i=0;i<n;i++)
        {
            cin>>s[i];
        }
        for(i=0;i<n;i++)
        for(j=0;j<n;j++)
        {
            ff(i,j);
        }
        cin>>d;
        for(i=0;i<n;i++)
        {
            if(s[i][0]==d)
            {
                vis[i]++;
                an=s[i].size();    //不要忘了这一句 而且是 = 不是+=!!
                dfs(i);
                vis[i]=0;
            }
        }
        cout<<ans;
     } 
  • 相关阅读:
    JavaScript 相关记录
    首页大图淡入淡出效果工具flexslider
    取消chrome浏览器下input和textarea的默认样式;html5默认input内容清除“×”按钮去除办法
    Hibernate入门笔记
    Servlet入门笔记
    父容器利用opacity设置透明后,子元素跟着变透明的解决方案
    overflow:hidden与margin:0 auto之间的冲突
    初识Android Studio
    首页图片滚动效果
    DIV宽度设置成100%,浏览器窗口缩小后,右边出现留白
  • 原文地址:https://www.cnblogs.com/dyhaohaoxuexi/p/10612722.html
Copyright © 2011-2022 走看看