【NOIP2000】单词接龙

来源:互联网 发布:mysql 触发器 存储过程 编辑:程序博客网 时间:2024/06/04 17:43

1018 单词接龙 2000年NOIP全国联赛普及组NOIP全国联赛提高组
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 黄金 Gold

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

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

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

样例输入 Sample Input
5
at
touch
cheat
choose
tact
a

样例输出 Sample Output
23

数据范围及提示 Data Size & Hint
(连成的“龙”为atoucheatactactouchoose)

看数据范围n比较小所以可以直接搜索
注意子串最多出现两次
重叠部分不算

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAXN = 55;string word[MAXN];//记录题目所给单词int n,use[MAXN];//记录每个单词使用次数int ans = 0; //答案string begin;//开头字母bool can(string s,string m,int k){    /*        现在我手上有两个串        然后我比较这两个串能不能接起来        就是某串的前几个字母是不是和另一个串的后几个相同        k是一个下标,代表现在手里这两个串是由原题中某两个串截取到k || 从k截取     */    int lens = s.length();    for(int i = 0;i < k; i ++)        if(s[lens - k + i] != m[i])            return false;//接不起来QAQ不能在一起     return true;}void add(string &s,string m,int k)//接龙 {    /*        k是从哪里开始不一样 就是从哪里开始接龙        字符串的优势出现了 支持+=这种类型的操作        比如 string a = 'abc';char b = 'd';        a += b;a = 'abcd';        这里就是把部分m接到s上     */    int lenm = m.length();    for(int i = k; i < lenm; i ++)        s += m[i];    return;}void dfs(string now){    /*        我现在手里有一个串        先看这个串是不是能更新答案        再看别的串能不能接上        注意每个串可以用两次     */    int x = now.length();    ans = max(ans,x);    for(int i = 1; i <= n; i ++)    {        if(use[i] >= 2) continue;//用了两次了不能用了QAQ        int zl = word[i].length();        for(int j = 1; j <= zl; j ++)        {            //枚举一下看看能从哪里开始接龙 还是根本不能在一起QAQ             if(can(now,word[i],j))//如果可以             {                string temp = now;                /*关于为什么要复制:                    因为当前接龙不一定最优                    比如这个样例  touch可以接cheat也可以接choose                    看起来choose更优 然而对于整个题目 cheat更优                    醒醒,这是搜索,不要贪心                 */                 add(temp,word[i],j);                if(temp == now) continue;//如果接龙和现在相同就算了 肯定不如不接优                 use[i] ++;//                dfs(temp);//从接龙之后的串继续搜                 use[i] --; //还原             }         }     }    return;}int main(){    scanf("%d",&n);    for(int i = 1; i <= n; i ++)        cin >> word[i];    cin >> begin;//以这个字母为开头接龙 那就从它开始搜吧     dfs(begin);    printf("%d\n",ans);    return 0;}
1 0
原创粉丝点击