使用BFS去搜索每一个可以添加的单词,然后将所有的可能性搜索一遍之后取最大的。
关键点:如何进行字符串的匹配:将s1从后向前遍历,如果与s2的第一个匹配上了就接着向前走,如果知道s1的末尾都通过的话就证明可以匹配上。不用真的拼接上去,只需要记录拼接后的长度就行。
拼接后的长度:两个字符串的长度之和-重复的长度。
#include <bits/stdc++.h> using namespace std; const int maxn = 20+4; string s[maxn]; int begin_pos[maxn]; int cnt = 0; map<int, int> mp; char beginc; int n; int temp = -1; //判断s1的末尾和s2的首部是否有重叠之处,返回重叠的长度 int check(string s1, string s2) { bool flag = true; for (int i=s1.length()-1; i>=0; i--) { if (s1[i]==s2[0]) { int pos = 0; for (int j=i;j<s1.length();j++) { if (s1[j]!=s2[pos++]) { flag = false; break; } } if (flag) { return pos; } } } return 0; } int DFS(string last, int num) { for (int i=0;i<n;i++) { if (mp[i]==2) continue; int repeat_len = check(last, s[i]); if (repeat_len) { mp[i]++; DFS(last+s[i], num+s[i].length()-repeat_len); mp[i]--; } } return temp = max(temp, num); } int main() { cin>>n; for (int i=0;i<n;i++) { cin>>s[i]; } cin>>beginc; for (int i=0;i<n;i++) { if (s[i][0]==beginc) { begin_pos[cnt++] = i; } } int ans = 0; //以不同的单词开头去进行DFS搜索 for (int i=0;i<cnt;i++) { mp.clear(); mp[begin_pos[i]] = 1; ans = max(ans, DFS(s[begin_pos[i]], s[begin_pos[i]].length())); } cout<<ans; return 0; }