[UVA 1608] Non-boring sequences

We were afraid of making this problem statement too boring, so we decided to keep it short. A sequence is called non-boring if its every connected subsequence contains a unique element, i.e. an element such that no other element of that subsequence has the same value. Given a sequence of integers, decide whether it is non-boring.
Input
The first line of the input contains the number of test cases T T T. The descriptions of the test cases follow: Each test case starts with an integer n n n ( 1 ≤ n ≤ 200000 1 ≤ n ≤ 200000 1n200000) denoting the length of the sequence. In the next line the n elements of the sequence follow, separated with single spaces. The elements are non-negative integers less than 109.
Output
Print the answers to the test cases in the order in which they appear in the input. For each test case print a single line containing the word ‘non-boring’ or ‘boring’.
Sample Input


4
5
1 2 3 4 5
5
1 1 1 1 1
5
1 2 3 2 1
5
1 1 2 1 1

Sample Output

non-boring
boring
non-boring
boring

题意
(有 T T T组数据) 每组数据给出一个 n n n与一个长为 n n n的数列,其中每个数为小于109的非负整数。若这个数列中每个连续的子数列都包含有(至少)一个与该子数列中其它任何数都不同的数,则输出“non-boring”,否则输出“boring”。
思路
考虑一个数列是自身的子数列,显然在整个数列中至少要有一个与其它任何数都不同的数。于是问题就转化为分析这个数两边的子数列是否是“non-boring”数列(因为包含这个数的子数列必然是“non-boring”数列)。对于左边(右边)的数列,同样可以通过寻找是否有与其他任何数都不同的数来把这个数列分割为一个更小的数列。或者不存在这个数,则整个数列为“boring”数列。
考虑 n n n最大为 200000 200000 200000且有多组数据,每次直接遍历整个子数列必然时间复杂度爆炸,所以可以用一个pre[]数组来存储 a [ i ] a[i] a[i]前面最近的与 a [ i ] a[i] a[i]相同的数的位置,一个aft[]数组来存储 a [ i ] a[i] a[i]后面最近的与 a [ i ] a[i] a[i]相同的数的位置,这样可以把每次寻找的时间复杂度降到O(1)。
特别注意
经测试,这样依然会TLE,将每次查询子数列中是否存在与a[i]相同的数的方式由从一端开始遍历改为从两端同时遍历就顺利A掉了这一题
AC版本代码

#include<map>
#include<set>
#include<stdio.h>
using namespace std;
int t,n;
int a[200010];
int pre[200010];
int aft[200010];
map<int,int>m;
map<int,int>::iterator it;
bool sear(int l,int r)
{
 if(l>=r) return 1;
 int i;
 for(i=0;l+i<=r-i;i++) 
 {
  if(pre[l+i]<l&&(aft[l+i]>r||aft[l+i]==0)) return sear(l,l+i-1)&&sear(l+i+1,r);
  if(pre[r-i]<l&&(aft[r-i]>r||aft[r-i]==0)) return sear(l,r-i-1)&&sear(r-i+1,r);
 }
 return 0;
}
int main()
{
 scanf("%d",&t);
 while(t--)
 {
  bool flag=0;
  scanf("%d",&n);
  for(int i=1;i<=n;i++) 
  {
   scanf("%d",&a[i]);
   
   it=m.find(a[i]);
   if(it==m.end())
    m.insert(pair<int,int>(a[i],i));
   else {
    pre[i]=(*it).second;
    aft[(*it).second]=i;
    (*it).second=i;
   }
  }
  if(flag) {printf("boring\n");m.clear();continue;}
  flag=sear(1,n);
  if(flag) printf("non-boring\n");else printf("boring\n");
  for(int i=1;i<=n;i++) pre[i]=aft[i]=0;
  m.clear();
 }
 return 0;
}

TLE版本代码

#include<map>
#include<set>
#include<stdio.h>
using namespace std;
int t,n;
int a[200010];
int pre[200010];
int aft[200010];
map<int,int>m;
map<int,int>::iterator it;
bool sear(int l,int r)
{
	if(l>=r) return 1;
	int i;
	for(i=0;l+i<=r-i;i++) 
	{
		if(pre[l+i]<l&&(aft[l+i]>r||aft[l+i]==0)) return sear(l,l+i-1)&&sear(l+i+1,r);
		if(pre[r-i]<l&&(aft[r-i]>r||aft[r-i]==0)) return sear(l,r-i-1)&&sear(r-i+1,r);
	}
	return 0;
}
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		bool flag=0;
		scanf("%d",&n);
		for(int i=1;i<=n;i++) 
		{
			scanf("%d",&a[i]);
			
			it=m.find(a[i]);
			if(it==m.end())
				m.insert(pair<int,int>(a[i],i));
			else {
				pre[i]=(*it).second;
				aft[(*it).second]=i;
				(*it).second=i;
			}
		}
		if(flag) {printf("boring\n");m.clear();continue;}
		flag=sear(1,n);
		if(flag) printf("non-boring\n");else printf("boring\n");
		for(int i=1;i<=n;i++) pre[i]=aft[i]=0;
		m.clear();
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值