Codeforces Round #767 (Div. 2) - D
题目翻译
米海计划看一部电影。他只喜欢回文电影,所以他想跳过一些(可能零)场景,使电影的其余部分回文。
你会得到一个n非空字符串列表,长度最多为3,代表米海电影的场景。
如果s的子序列是非空的,且子序列中的字符串按顺序连接为回文,则称其为awesome。
你能帮Mihai检查一下s是否至少有一个awesome的子序列吗?
回文是一个前后读相同的字符串,例如字符串“z”、“aaa”、“aba”、“abccba”是回文,而字符串“codeforces”、“reality”、“ab”则不是。
序列a是非空序列b的非空子序列,如果a可以通过删除几个(可能是零,但不是全部)元素从b获得。
输入
输入的第一行包含一个整数t(1≤T≤100)-测试用例的数量。测试用例的描述如下。
每个测试用例的第一行包含一个整数n(1≤N≤1e5)-电影中的场景数量。
然后是n行,第二行包含一个长度不超过3的非空字符串si,由小写拉丁字母组成。
保证所有测试用例的n之和不超过1e5。
输出
对于每个测试用例,如果s的子序列很棒,则打印“YES”,否则打印“NO”(不区分大小写)。
样例
输入
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
输出
YES
NO
NO
YES
YES
NO
解题思路
因为题目说,答案是可以从给出的几个字符串中按顺序选出来的,所以我们其实只要考虑其中的字符串是否有只有一个字符的,或者有某个字符串有两个字符且这两个字符相等。如果上述情况都不满足,那么就有点小麻烦,我们可以用个 map 存储,之后再判断是否有对应的字符串,结合起来能实现回文。
代码示例
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
int t;
int n;
map<string,int> s;
int main(){
cin>>t;
while(t--){
cin>>n;
int ok=0;
for(int i=1;i<=n;i++){
string a;
cin>>a;
if(ok) continue;
if(a.size()==1||a[0]==a[a.size()-1]) ok=1;
if(a.size()==2){
string b=a;
reverse(b.begin(),b.end());
if(s.count(b)) ok=1;
s[a]=2;
}
if(a.size()==3){
string pre=a.substr(0,2),nx=a.substr(1),A=a;
reverse(nx.begin(),nx.end());
reverse(A.begin(),A.end());
if(s.count(nx)&&s[nx]==2) ok=1;
if(s.count(A)) ok=1;
s[a.substr(0,2)]=3,s[a]=3;
}
}
if(ok==1) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
s.clear();
}
}