题解
给你n个串 这n个串都看作一个环 问n个串的最长公共子序列(不连续) 输出字典序最小的一个
暴力枚举第一个串的子序列(最多2^8个) 然后用string和rotate暴力尝试答案是否正确 最后找字典序最小 注意只有一个串的时候也需要找字典序最小
AC代码
#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
int main()
{
#ifdef LOCAL
freopen("C:/input.txt", "r", stdin);
#endif
int n;
while (cin >> n)
{
string s[20];
vector<string> ans;
for (int i = 0; i < n; i++)
cin >> s[i];
if (n == 1)
{
string res(s[0].size(), 'z');
for (int j = 0; j < s[0].size(); j++)
{
if (s[0] < res)
res = s[0];
rotate(s[0].begin(), s[0].begin() + 1, s[0].end());
}
cout << res << endl;
continue;
}
for (int i = (1 << s[0].size()) - 1; i >= 1; i--) //子串掩码
{
string sub;
for (int j = 0; j < s[0].size(); j++)
if (i & (1 << j))
sub.push_back(s[0][j]);
//cout << endl; /
for (int j = 0; j < sub.size(); j++) //子串旋转
{
int can = 1; //全部满足
for (int k = 1; k < n && can; k++) //其它串
{
int flag = 0; //一个位置满足
for (int l = 0; l < s[k].size() && !flag; l++) //其它串旋转
{
int last = -1, cnt = 0; //上次位置 匹配个数
for (int p = 0; p < sub.size(); p++) //s[k]找sub
for (int q = last + 1; q < s[k].size(); q++)
if (sub[p] == s[k][q])
{
last = q, cnt++;
break;
}
if (cnt == sub.size())
flag = 1;
rotate(s[k].begin(), s[k].begin() + 1, s[k].end());
}
if (!flag)
can = 0;
}
if (can)
{
if (!ans.empty() && sub.size() > ans[0].size())
ans.clear();
if (ans.empty() || sub.size() == ans[0].size())
ans.push_back(sub);
break;
}
rotate(sub.begin(), sub.begin() + 1, sub.end());
}
}
if (ans.size())
{
string res(ans[0].size(), 'z');
for (int i = 0; i < ans.size(); i++)
{
for (int j = 0; j < ans[0].size(); j++)
{
if (ans[i] < res)
res = ans[i];
rotate(ans[i].begin(), ans[i].begin() + 1, ans[i].end());
}
}
cout << res << endl;
}
else
cout << 0 << endl;
}
return 0;
}