zoukankan      html  css  js  c++  java
  • ●UVA 1608 Non-boring sequences

    题链:

    https://vjudge.net/problem/UVA-1608#author=chenchonghan
    题解:

    分治
    如果一个区间[l,r]里面在p位置出现了一个只出现一次的元素,(如果不存在该元素,该区间就是boring的)
    那么必然包含p的子区间都是non-boring的。
    即如果存在boring的区间,必然是[l,p-1],[p+1,r]的子区间。
    所以继续递归处理上面两个区间即可。
    (判断某个元素是否在区间里只出现一次,只需考虑它左边第一个与它相同的元素或它右边第一个相同的元素是否在该区间里)
    (需要O(N)预处理L[i],R[i]分别表示该位置左边和右边第一个与该位置相同的位置)
    复杂度最坏O(N^2),不够高效。
    优化就是从区间的两端同时寻找是否存在该区间内只出现一次的元素。


    代码:

    #include<bits/stdc++.h>
    #define MAXN 200005
    using namespace std;
    int N;
    int L[MAXN],R[MAXN];
    void read_and_prework(){
    	static int A[MAXN],tmp[MAXN],tnt;
    	scanf("%d",&N);
    	for(int i=1;i<=N;i++)
    		scanf("%d",&A[i]),tmp[i]=A[i];
    	sort(tmp+1,tmp+N+1);
    	tnt=unique(tmp+1,tmp+N+1)-tmp-1;
    	for(int i=1;i<=N;i++)
    		A[i]=lower_bound(tmp+1,tmp+tnt+1,A[i])-tmp;
    	fill(tmp+1,tmp+tnt+1,0);
    	for(int i=1;i<=N;i++)
    		L[i]=tmp[A[i]],tmp[A[i]]=i;
    	fill(tmp+1,tmp+tnt+1,N+1);
    	for(int i=N;i>=1;i--)
    		R[i]=tmp[A[i]],tmp[A[i]]=i;
    }
    bool divide(int l,int r){
    	if(l==r) return 1;
    	bool fg=1;
    	int i=l,j=r,k=0;
    	while(i<=j){
    		if(L[i]<l&&R[i]>r){k=i; break;}
    		else i++;
    		if(L[j]<l&&R[j]>r){k=j; break;}
    		else j--;
    	}
    	if(!k) return 0;
    	if(l<=k-1) fg&=divide(l,k-1);
    	if(k+1<=r) fg&=divide(k+1,r);
    	return fg;
    }
    int main(){
    	int Case; scanf("%d",&Case);
    	while(Case--){
    		read_and_prework();
    		if(divide(1,N)) printf("non-boring");
    		else printf("boring");
    		printf("
    ");
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    去掉mysql数据库字段中的个别字符
    配置tomcat的虚拟路径
    log4j配置文件详解
    Eclipse Java注释模板设置详解
    OGNL表达式
    Struts2常用标签
    springMVC中ajax的使用
    springMVC配置文件位置及名称
    (转)Git Gui for Windows的建库、克隆(clone)、上传(push)、下载(pull)、合并
    采用U盘安装操作系统
  • 原文地址:https://www.cnblogs.com/zj75211/p/8541827.html
Copyright © 2011-2022 走看看