/*输入:
5
at touch cheat choose tact
a 龙头
输出:23
每个单词可以使用两次
*/
#include<iostream>
using namespace std;
string s[42], str/*用来拼接*/, res/*用来记录拼接串*/;
bool vis[42];//每个单词可以使用两次
int n;
char head;//龙头
int longest;//最大长度
int check(string s1, string s2) {//能否接龙
for (int i = s1.size() - 1; i >= 0; i--) {
//截取s1的后s1.size()-i个和s2的前s1.size()-i
if(s1.substr(i)==s2.substr(0,s1.size()-i))
return s1.size() - i;//返回截取个数
}
return -1;//不能,,返回-1
}
void dfs(string ans, int dep) {
if (ans.size() > longest) {
longest = ans.size();//更新最大长度
res = ans;//更新拼接串
}
if (dep == 2 * n + 1)return;//搜完了,返回
for (int i = 1; i <= 2 * n; i++) {
if (dep == 1 /*第一个单词*/ && s[i][0] == head/*单词的首字母只需要与指定字母相同*/ && !vis[i]) {
vis[i] = 1;
dfs(ans + s[i], dep + 1);//将单词加入到单词序列中,搜素下一个单词
vis[i] = 0;//回溯
}
else if (dep >= 2&&!vis[i]) {//不是第一个单词
int pos=check(ans, s[i]);//截取的下标
if (pos != -1) {//可以接龙
vis[i] = 1;//标记
dfs(ans + s[i].substr(pos), dep + 1);//加入接龙序列,继续搜下一个单词
vis[i] = 0;//回溯
}
}
}
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++) cin >> s[i];
//输入at touch cheat choose tact
for (int i = n + 1; i <= 2 * n; i++) s[i] = s[i - n];//复制一遍
//变为at touch cheat choose tact at touch cheat choose tact
cin >> head;
dfs(str, 1);
cout << res << endl;//输出最终接龙的字符串
cout<< longest << endl;//输出最大长度
return 0;
}
输入:
5
at touch cheat choose tact
a
输出:
atoucheatactactouchoose
23
486

被折叠的 条评论
为什么被折叠?



