zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    【性能诊断】十一、性能问题综合分析(案例2,windbg、wireshark)
    SQL Server常用的性能诊断语句
    Oracle常用的性能诊断语句
    【性能诊断】五、并发场景的性能分析(windbg简介及dump抓取)
    数据库管理与开发工具推荐---DBeaver
    DM达梦数据库---执行计划查看
    DM达梦数据库索引失效的处理---强制更新统计信息
    jProfiler、jMAT等工具注意设置启动的Xmx参数
    JVM启动参数建议
    Linux环境jcmd抓取进程信息及内存dump
  • 原文地址:https://www.cnblogs.com/EcliWalker/p/8353033.html
Copyright © 2011-2022 走看看