UVA 1608 不无聊的序列(中途相遇思想+递归)

题目:https://vjudge.net/problem/UVA-1608

用滑动窗口的方法把每个不唯一的数的左边和右边挑出来,这样就能找出唯一的数。

加速思想:普通的从左往右遍历会超时,所以选择左右同时进行遍历,次时最坏的情况是唯一元素在中间,相当于把每次

查找缩小了一半,若要查找n个数,那么时间复杂度为(n*logn),大大减小了查找时间。

#include<bits/stdc++.h>
using namespace std;

int a[200005];

int l[2000005],r[2000005];


bool judge(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 judge(left,left+i-1) && judge(left+i+1,right); 
		if(l[right-i]<left && r[right-i]>right)
		return judge(left,right-i-1) && judge(right-i+1,right);
	}
	
	return false;
	
}

map<int,int> m;
int main(){
	int n;
	scanf("%d",&n);
	while(n--){
		int n;
		scanf("%d",&n);
		for(int i=0;i<n;i++)
		scanf("%d",&a[i]);
		m.clear();
		
		for(int i=0;i<n;i++){
			if(m.count(a[i])!=0){
				l[i]=m[a[i]];
			}
			else{
				l[i]=-1;				
			}
			m[a[i]]=i;
		}
		
		m.clear();
		for(int i=n-1;i>=0;i--){
			if(m.count(a[i])!=0){
				r[i]=m[a[i]];				
			}
			else{
			    r[i]=n;
			}					
			m[a[i]]=i;
		}
		
		if(judge(0,n-1))
		printf("non-boring\n");
		else
		printf("boring\n");		
	}	
	
}
发布了57 篇原创文章 · 获赞 58 · 访问量 630

猜你喜欢

转载自blog.csdn.net/weixin_43568895/article/details/103704158