CF 127个测试点,好评
简要题意:
多组数据,问数组中是否有长度 \(\geq 3\) 的回文子序列。
我们需要找到本质。
题目不让我们求这个长度,只让我们判断,这是为什么呢?
如果答案是 YES
,那么必然存在一个长度为 \(3\) 的回文子序列。否则为 NO
.
你想,如果原数组的最长回文序列是奇数的话,只要每次在两边同时删去一个,就可以得到长度为 \(3\) 的回文子序列。
如果是偶数,只要每次在两边同时删去一个,再在最中间两个任意删去一个,也可以得到长度为 \(3\) 的回文子序列。
反之如果没有,则就没有了。
比方说:
10 1 2 3 4 2 1 4 2 4 3
你发现这个数组的最长回文子序列为:
3 4 2 2 4 3
是偶数,那么其中必然存在一个长度为 \(3\) 的是:
4 2 4
(当然不止一种)
所以,题意改为:
判断一个数组中是否有长度为 \(3\) 的回文子序列。
???这还用判断吗???
长度为 \(3\),中间数没有什么限制,旁边两个数相等即可。
也就是说,需要 找到两个相等的数,使得它们不相邻(即中间还放得下一个数,构成回文子序列) 。
???这还用判断吗???
显然,一波哈希解决问题。正好 \(a_i \leq n\),这不是天赐良机?
时间复杂度: \(O(T \times n)\).
空间复杂度: \(O(n)\).
实际得分: \(100pts\).
#pragma GCC optimize(2) #include<bits/stdc++.h> using namespace std; inline int read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();} int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;} int a[5001],n; int T; int main(){ T=read(); while(T--) { n=read(); bool f=0; memset(a,0,sizeof(a)); for(int i=1,t;i<=n;i++) { t=read(); if(a[t] && i-a[t]>1) f=1; if(!a[t]) a[t]=i; } if(f) puts("YES"); else puts("NO"); } return 0; }
来源:https://www.cnblogs.com/bifanwen/p/12550080.html