题目描述单词接龙是一个与咱们常常玩的成语接龙相相似的游戏,如今咱们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每一个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如beastbeastbeast 和 astonishastonishastonish ,若是接成一条龙则变为beastonishbeastonishbeastonish ,另外相邻的两部分不能存在包含关系,例如 atatat 和atideatideatide 间不能相连。ios
输入格式:ide
输入的第一行为一个单独的整数
n*n (n≤20)
表示单词数,如下n*n
行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你能够假定以此字母开头的“龙”必定存在.idea输出格式:spa
只需输出以此字母开头的最长的“龙”的长度code
来源
洛谷P1019 游戏鉴定
读题有坑
注意max_初始化ci
短小精悍(?)的深搜代码:字符串
#include <iostream> #include <string> using namespace std; int n,max_; string str[20]; int b[20]; int mix(string str1, string str2) {//若是没有重叠部分就返回-1,不然返回重叠部分开始的位置 for(int k=str1.size()-1; k>=0; k--) {//贪心,为了让合并后的字符串尽可能长必定要从后往前判断 bool r=1; int i_2=0; for(int i=k; i<=str1.size()-1; i++) { if(!(i_2<=str2.size()-1)) {//判断str2边界 r=0; break; } else if(str1[i]!=str2[i_2]) { r=0; break; } i_2++; } if(r) return k; } return -1; } void search(int cur, string s) { bool bb=1;//bb规定:0表示有至少一个解,1表示此状况无解 for(int i=0; i<n; i++) if(b[i]<=1) {//注意每一个单词能够用两次 bb=0; int t=mix(s,str[i]); if(t!=-1) { string news; for(int i=0; i<=t-1; i++) news+=s[i]; news+=str[i];//合并两个字符串 b[i]+=1; search(cur+1, news); b[i]-=1; } } if(bb&&max_<s.size()) max_=s.size();//更新max_ } int main() { ios::sync_with_stdio(false); cin>>n; for(int i=0; i<=n-1; i++) cin>>str[i]; char a; cin>>a; for(int i=0; i<n; i++) if(str[i][0]==a) {//枚举每一个以字符a开头的字符串 b[i]=1; string t=str[i]; if(max_<t.size()) { max_=t.size();//初始化max_ } search(0, t);//开搜! b[i]=0; } cout<<max_; return 0; }