题意:给定一段序列,如果这段序列的任意连续子序列中至少存在一个数唯一,那么这段序列就是Non-boring,否则就是boring,判定这段序列是否boring
思路:如果一个数A[x]是全场唯一,那么我们只需判断A[1]~A[x-1] 和A[x+1]~A[n]是否满足要求,为什么呢?因为A[x]全场唯一,所以经过A[x]的连续字段必然是Non-boring的,所以我们可以设计一个递归函数bool isBor(int l,int r)判断区间l~r是不是boring的,并且,我们还需要通过map的方式预处理每个序列左边和右边离他最近的相同距离的下标
递归的时候为了保证效率,我们从中间开始寻找唯一序列,代码如下:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<vector>
#include<set>
#include<map>
using namespace std;
const int maxn=200000+5;
int L[maxn],R[maxn],A[maxn];
int n;
map<int,int>MAP;
inline bool get(int &t)
{
bool flag = 0 ;
char c;
while(!isdigit(c = getchar())&&c!='-') if( c == -1 ) break ;
if( c == -1 ) return 0 ;
if(c=='-') flag = 1 , t = 0 ;
else t = c ^ 48;
while(isdigit(c = getchar())) t = (t << 1) + (t << 3) + (c ^ 48) ;
if(flag) t = -t ;
return 1 ;
}
bool solve(int left, int right)
{
if(left >= right)
return true;
for(int i = 0; i <= (right - left) / 2; ++i){
if(L[left + i] < left && R[left + i] > right)
return solve(left, left + i - 1) && solve(left + i + 1,right);
if(L[right - i] < left && R[right - i] > right)
return solve(left,right - i - 1) && solve(right - i + 1, right);
}
return false;
}
int main()
{
int i,j;
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
get(A[i]);
// scanf("%d",&A[i]);
// memset(L,-1,sizeof L);
// memset(R,0x3f,sizeof R);
MAP.clear();
for(i=0;i<n;i++)
{
if(MAP.find(A[i])!=MAP.end())
{
L[i]=MAP[A[i]];
}
else
L[i]=-1;
MAP[A[i]]=i;
}
MAP.clear();
for(i=n-1;i>=0;i--)
{
if(MAP.find(A[i])!=MAP.end())
{
R[i]=MAP[A[i]];
}
else
R[i]=n;
MAP[A[i]]=i;
}
if(solve(0,n-1))
{
puts("non-boring");
}
else
{
puts("boring");
}
}
return 0;
}