题意:
给你n个字符串,每个字符串长度不超过3,问你能够选出一个子序列使得子序列构造的字符串为回文串。
题解:
可以知道如果有字符串本身是回文串的,那就能构造出来。
剩下两种情况:
1.长度为2时,假设字符串为ab。
①找出后面是否有长度为2且字符串为ba。
②找出后面长度为3的最后两个字符为ba。
2.长度为3时,假设字符串为abc:
①找出后面长度为2且字符串为ba
②找出后面长度为3且字符串为cba。
可以看到长度为2和3时候的差别在于第二个,那么我们可以用哈希来做这道题.
map[0]存的是长度为2的字符串
map[1]存的是长度为3的字符串
长度为3的字符串由于查询的时候有两种情况,所以我们做到长度为3的字符串的时候将两种情况都塞到map[1]里面。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
map<int,int>mp[2];
char ss[N][5];
int main()
{
char s[5];
int t;
scanf("%d",&t);
while(t--){
int n,f=0;
scanf("%d",&n);
mp[0].clear(),mp[1].clear();
for(int i=1;i<=n;i++)scanf("%s",ss[i]);
for(int i=n;i;i--){
strcpy(s,ss[i]);
if(f)break;
int has=0,len=strlen(s);
if(len==1)f=1;
else if(len==2){
if(s[0]==s[1])f=1;
has=(int)s[0]*1000+(int)s[1];
if(mp[0][has]||mp[1][has])f=1;
has=(int)s[1]*1000+(int)s[0];
mp[0][has]=1;
}
else{
if(s[0]==s[2])f=1;
has=(int)s[0]*1000+(int)s[1];
if(mp[0][has])f=1;
has=has*1000+(int)s[2];
if(mp[1][has])f=1;
has=((int)s[2]*1000+(int)s[1])*1000+(int)s[0];
mp[1][has]=1;
has=(int)s[2]*1000+(int)s[1];
mp[1][has]=1;
}
}
printf("%s\n",f?"YES":"NO");
}
return 0;
}