题目链接:P1019 单词接龙
我为这里比较难的地方就是处理两个单词的最小重叠部分,并且不允许包含关系,这里需要写一个函数来处理两个字符串的最小重叠部分。
int getlen(char a[], char b[] ) { int len1 = strlen(a), len2 = strlen(b); for (int i = 1; i < min(len1, len2); i++)//枚举最小重叠长度,而且保证不会让包含关系满足 { bool flag = true; for (int j = 0; j < i; j++) { if (a[len1 - i + j] != b[j]) { //从a的末尾的第i个与b第1个开始匹配 flag = false; break; } } if (flag) return i; } return 0; }
这里处理完了剩下的就是搜索了
#include<bits/stdc++.h> #include<unordered_map> using namespace std; const int N = 1e5 + 5; char word[25][N]; int used[25]; int n,ans; char start; int getlen(char a[], char b[] ) { int len1 = strlen(a), len2 = strlen(b); for (int i = 1; i < min(len1, len2); i++) { bool flag = true; for (int j = 0; j < i; j++) { if (a[len1 - i + j] != b[j]) { flag = false; break; } } if (flag) return i; } return 0; } void dfs(int step, int len) { ans = max(ans, len); for (int i = 0; i < n; i++) { if (used[i] >= 2) continue; int len1 = getlen(word[step], word[i]); cout << len1 << " " << word[i]<<endl; if (len1) { used[i]++; dfs(i, len + strlen(word[i]) - len1); used[i]--; } } } int main() { cin >> n; for (int i = 0; i < n; i++) scanf("%s", word[i]); cin >> start; for (int i = 0; i < n; i++) { if (word[i][0] == start) { used[i]++; dfs(i, strlen(word[i])); used[i]--; } } cout << ans<<endl; return 0; }