单词接龙 题解

题目描述

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

输入格式

输入的第一行为一个单独的整数

n 表示单词数,以下

n 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在。

输出格式

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

#include<bits/stdc++.h>
#define gc ch=getchar()
#define ps puts("")
#define pc putchar(32)
#define INF 0x3f3f3f3f
using namespace std;
const int N = 1e3+10;
template <class T>void read(T &s){
     s=0;T f=1;char gc;
     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;gc;}
     while(ch<='9'&&ch>='0'){s=s*10+ch-'0';gc;}
     s*=f;
}
template <class T>void put(T s){
     if(s<0)s=-s,putchar('-');
     if(s>9)put(s/10);
     putchar(s%10+'0');
}
int ans=-INF;//最终答案串的长度;
string words[N];//记录单词;
string start;
int max(int a,int b){
     if(a>b) return a;
     else return b;
}
int use[N];//一个单词最多被使用两次
int n;
bool check(string a,string b,int len){//判断b是否能作为最长接续字符串;
     //len为接口(重合)长度(从1 开始枚举)
     int lens=a.length();
     for(int i=0;i<len;i++){
          if(a[lens-len+i]!=b[i])//头串末尾与尾串开头进行比较,
               return false;
     }
     return true;//对比成功,这个长度可以接续
}
void addstring(string &a,string b,int len){
     int lens=b.length();
     for(int i=len;i<lens;i++)
          a+=b[i]; //cpp 字符串特性,取地址 直接拼接字符;
}
void dfs(string str){
     int lens=str.length();
     ans=max(ans,lens);//更新答案串长度;
     for(int i=1;i<=n;i++){
          if(use[i]>=2) continue;
          int maxnlens=words[i].length();
          //最大的重合长度 我们要使得它尽可能小->从小枚举看看能否接续
          for(int j=1;j<=maxnlens;j++){
               if(check(str,words[i],j)){
                    //如果能接,就接看看
                    string temp=str;
                    addstring(temp,words[i],j);
                    if(temp.length() == str.length()) continue;
                         //长度没变 加个屁;
                    use[i]++;
                    dfs(temp);
                    //如果加了 就从新串开始尝试拼接
                    use[i]--;
                         //回溯
               }
          }
     }
}//dfs搜索结果
int main(){
     memset(use,0,sizeof(use));
     read(n);
     for(int i=1;i<=n;i++)
          cin>>words[i];
     cin>>start;
     dfs(start);
     put(ans);
     return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值