题意:n段字符串经过删除几段字符串后按照输入顺序连接起来能否形成回文串,且每段字符串长度小于等于3。
题解:
能形成回文串情景:
(1)将其中一段字符串逆转后可以在输入的字符串中找到。
(2)其中有一段长度为一的字符串,本身形成回文串。
(3)其中有长度为二的字符串,且,两个字符相等,本身形成回文串。
(4)其中有长度为三的字符串,且将前两个字符逆转后所形成的字符串在它的后面可以找到相等的。(如ba,abc)ba出现在abc的前面则不能形成回文串。
(5)其中有长度为三的字符串,且将后两个字符逆转后所形成的字符串在它的前面可以找到相等的。(如abc,cb)cb出现在abc的后面则不能形成回文串。
只需考虑这五种情况即可。
代码如下:
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define int long long
#define endl '\n'
#define N 100005
using namespace std;
const int inf=0x3f3f3f3f;
const double ex=1e-7;
const int mod=1e9+7;
int gcd(int a ,int b){ return b ? gcd(b,a%b) : a ;}
map<string,int>m;
multiset<string>p;
void solve()
{
int n;
m.clear(),p.clear();
string t;
vector<string>s;
cin >>n;
for(int i=0;i<n;i++)
{
cin >>t;
s.push_back(t);
m[t]++;
}
for(int i=0;i<n;i++)
{
p.insert(s[i]);
m[s[i]]--;
t=s[i];
reverse(t.begin(),t.end());
if(m[t])
{
cout <<"YES"<<endl;return ;
}
if(s[i].size()==1)
{
cout <<"YES"<<endl;return ;
}
if(s[i].size()==2)
{
if(s[i][0]==s[i][1])
{
cout <<"YES"<<endl;return ;
}
}
if(s[i].size()==3)
{
if(s[i][0]==s[i][2])
{
cout <<"YES"<<endl;return ;
}
t=s[i].substr(1,2);
reverse(t.begin(),t.end());
if(p.count(t))
{
cout <<"YES"<<endl;return ;
}
t=s[i].substr(0,2);
reverse(t.begin(),t.end());
if(m[t])
{
cout <<"YES"<<endl;return ;
}
}
}
cout <<"NO"<<endl;
}
signed main()
{ios
int t;
cin >>t;
while(t--)
{
solve();
}
return 0;
}