每天一道英文题,ICPC不自闭(29)

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();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值