UVA - 1608 Non-boring sequences(递归分治,中途相遇)

本文介绍了一种用于判断数字序列是否为不无聊序列的有效算法。所谓不无聊序列是指序列中每个子序列至少包含一个唯一不重复的数字。通过递归检查及利用辅助数组记录每个数字最近的位置坐标来实现快速判断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

点击打开题目链接

题目大意:

给出一个N长度的数字序列,对于任一子序列中,都存在唯一不重复出现的数字,则称为不无聊序列,否则为无聊序列。

思路:

如果某个数字a[i]在序列中只出现一次,那么任何包含a[i]的序列都是不无聊的,则只需要考虑i-1的序列和i+1的序列是否满足。以此类推,递归下去。

问题则转变成判断某个数字在某子序列中是否唯一。方法是用l[i],r[i]两个数组分别记录总序列中第i个元素左边和它相等的最近的位置坐标和右边和它相等的最近的位置坐标。

在查找时为了避免极端情况,可以分别从1->n和n->1遍历查找。

附上AC代码:

#include<bits/stdc++.h>

using namespace std;
const int maxn = 200000 + 5;
int ln[maxn], rn[maxn];
int e[maxn];
map<int, int> _m;
int T, n;

int uniq(int t, int l, int r) {
    return ln[t] < l && rn[t] > r; 
}

int check(int l, int r) {
    if(l >= r) return 1;
    for(int i = 0; l + i <= r - i; i++) {
        if(uniq(l + i, l, r)) return check(l + i + 1, r) && check(l, l + i - 1);
        if(uniq(r - i, l, r)) return check(l, r - i - 1) && check(r - i + 1, r);
    }
    return 0;
}

int main() {
    ios :: sync_with_stdio(false);
    cin >> T;
    while(T--) {
        cin >> n;
        for(int i = 0; i < n; i++) {
            cin >> e[i];
        }
        //由左向右遍历
        _m.clear();
        for(int i = 0; i < n; i++) {
            if(!_m.count(e[i]) ) ln[i] = -1;
            else ln[i] = _m[e[i] ];
            _m[e[i] ] = i;
        }
        //由右向左遍历
        _m.clear();
        for(int i = n - 1; i >= 0; i--) {
            if(!_m.count(e[i]) ) rn[i] = n;
            else rn[i] = _m[e[i] ];
            _m[e[i] ] = i;
        }
        if(check(0, n - 1) )
            cout<<"non-boring"<<endl;
        else 
            cout<<"boring"<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chook_lxk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值