• UVA 1608 Non-boring sequences (分冶+递归)


    一、题目概述

    二、题目释义

    要求序列s的所有子序列,若所有这些子序列中均存在一个自己序列内是唯一的数,则称这个序列s是不无聊的

    三、思路分析

    从序列s开始考虑,序列s的整个长度为n,若序列s中存在一个唯一数,则所有包含了这个数的子序列都是不无聊的,那么有可能不满足的要求的子序列只会存在于这个唯一数的左区间与有区间,那么问题就被分冶为了看左区间与右区间内是否有一个唯一数,若找到了,则继续这样递归下去,直到靠近区间长度为1为止

    那么我们怎么样做到快速的查找在区间【l,r】内存在着唯一数呢,我们容易想到可以从两端向中间遍历,这样可以将复杂度整体 / 2,但是我们还缺少一个找到唯一数的办法,遍历只是纯粹的搜索并不能帮助我们判断,那么这么判断呢,用数组来保存?不存在的(手动滑稽)。这里可以有一个非常巧妙的预处理,我们当我们找到一个唯一数时,我们总是去继续检索它的左右区间,也就意味着这个唯一数是在它的左区间不曾出现过,在它的右区间也不曾出现过,那么我们可以为序列s的每一个 i 设置两个表示它们的左右区间是否有和它一样的数 pre[] 与 nex[],若没有则左区间记为一个极小数,右区间则记录为一个极大数,若存在则记录那个最靠近它的数的位置。这个记录过程可以由map映射来完成。

    四、AC代码

    #include <iostream>
    #include <cstdio>
    #include <map>
    
    using namespace std;
    const int N = 2e5+5;
    
    int a[N];
    int pre[N],nxt[N];
    map<int,int> mp;
    
    inline bool is_unique(int p,int l,int r)
    {
        return pre[p]<l && nxt[p]>r;
    }
    
    bool check(int l, int r)
    {
        if(l>=r) return 1;
        for(int d=0; l+d<=r-d; d++)
        {
            if(is_unique(l+d,l,r))
                return check(l,l+d-1) && check(l+d+1,r);
    
            if(l+d == r-d) return 0;
    
            if(is_unique(r-d,l,r))
                return check(l,r-d-1) && check(r-d+1,r);
        }
        return 0;
    }
    
    int main()
    {
        int T,n;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            int flag = 0;
            mp.clear();
            for(int i=0; i<n; i++)
            {
                scanf("%d",&a[i]);
                if(!mp.count(a[i]))
                    pre[i] = -1;
                else
                    pre[i] = mp[a[i]];
                mp[a[i]] = i;
            }
            mp.clear();
            for(int i=n-1; i>=0; i--)
            {
                if(!mp.count(a[i]))
                    nxt[i] = n;
                else
                    nxt[i] = mp[a[i]];
                mp[a[i]] = i;
            }
            for(int i=1; i<n; i++)
            {
                if(a[i] == a[i-1])
                {
                    flag = 1;
                    break;
                }
            }
            if(flag) printf("boring
    ");
            else
            {
                if(check(0,n-1)) printf("non-boring
    ");
                else printf("boring
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    linux源码方式安装Apache
    linux的chmod,chown命令详解
    2011年10月18日
    mysql检查查询及索引效率方法(explain)
    php中英文字符串的研究
    2011年10月20日
    PHP JSON中文乱码解决方法大全
    解决PHP下载文件名中文乱码
    php字符串学习笔记
    CSU_BMW正式组队纪念赛出题+部分解题报告
  • 原文地址:https://www.cnblogs.com/EcliWalker/p/8353033.html
Copyright © 2020-2023  润新知