Mihai plans to watch a movie. He only likes palindromic movies, so he wants to skip some (possibly zero) scenes to make the remaining parts of the movie palindromic.
You are given a list ss of nn non-empty strings of length at most 33, representing the scenes of Mihai's movie.
A subsequence of ss is called awesome if it is non-empty and the concatenation of the strings in the subsequence, in order, is a palindrome.
Can you help Mihai check if there is at least one awesome subsequence of ss?
A palindrome is a string that reads the same backward as forward, for example strings "z", "aaa", "aba", "abccba" are palindromes, but strings "codeforces", "reality", "ab" are not.
A sequence aa is a non-empty subsequence of a non-empty sequence bb if aa can be obtained from bb by deletion of several (possibly zero, but not all) elements.
Input
The first line of the input contains a single integer tt (1≤t≤1001≤t≤100) — the number of test cases. The description of test cases follows.
The first line of each test case contains a single integer nn (1≤n≤1051≤n≤105) — the number of scenes in the movie.
Then follows nn lines, the ii-th of which containing a single non-empty string sisi of length at most 33, consisting of lowercase Latin letters.
It is guaranteed that the sum of nn over all test cases does not exceed 105105.
Output
For each test case, print "YES" if there is an awesome subsequence of ss, or "NO" otherwise (case insensitive).
Example
input
Copy
6 5 zx ab cc zx ba 2 ab bad 4 co def orc es 3 a b c 3 ab cd cba 2 ab ab
output
Copy
YES NO NO YES YES NO
Note
In the first test case, an awesome subsequence of ss is [ab,cc,ba][ab,cc,ba]
思路:
具体思路请参看代码细节
代码:
string s[maxj];
void solve(){
//审题不清,有一个回文字符串或者有一对回文字符串就行
//相等才是相等
int n;cin>>n;
map<string,int>two,three;//按顺序的2对2,或者2对3匹配,map实现O(n)的复杂度
bool ff=1;
for(int i=1;i<=n;++i){
cin>>s[i];
three[s[i]]++;
if(s[i].size()==1){
ff=0;
}else if(s[i].size()==2){
if(s[i][0]==s[i][1]){
ff=0;
}
}else{
if(s[i][0]==s[i][2]){
ff=0;
}
}
}
if(!ff){//本身是回文,结束
cout<<"YES"<<'\n';
return ;
}
for(int i=1;i<=n;++i){
if(s[i].size()==2){
string x=s[i];
reverse(x.begin(),x.end());
if(two[x]){
cout<<"YES"<<'\n';
return ;
}
two[s[i]]++;
}else {
string x;
x=s[i];
reverse(x.begin(),x.end());
if(three[x]){
cout<<"YES"<<'\n';
return ;
}
string s1="";
string s2="";
s1+=s[i][0];
s1+=s[i][1];
s2+=s[i][1];
s2+=s[i][2];
reverse(s1.begin(),s1.end());//和后边2个的匹配
reverse(s2.begin(),s2.end());//和前边2个的匹配
if(two[s2]||three[s1]){
cout<<"YES"<<'\n';
return ;
}
}
three[s[i]]--;//保证按顺序搭配,和后边搭配
}cout<<"NO"<<'\n';
}