UVA 1608 Non-boring sequences

来源:互联网 发布:js添加属性checked 编辑:程序博客网 时间:2024/05/16 08:35

题意:如果一个序列的任意连续子序列中至少有一个只出现一次的元素,则称这个序列不无聊,输入一个n个元素的序列A,判断它是不是无聊的串

解题思路:分治.假设原先数组中存在一个仅出现一次的数,假设其位置为p,则很容易知道包含p的所有区间都是不无聊的,因为p位置上的数字在整个序列中仅出现过一次。那么只需要判断[1,p-1]和[p+1,n]其相对应的子区间即可。其中判断某一个区间内某一个数是否仅出现过一次的时候,只需要判断和它相同且距离最近的左边和右边的数是否也在此区间内即可,可以通过预处理出l[i]和r[i],然后从两边向中间寻找,这种解题方式就是分治的思想

代码:

#include <iostream>#include <algorithm>#include <cstring>#include <string>#include <cmath>#include <cstdio>using namespace std;const int maxn=200000+10;int pos[maxn],a[maxn];int l[maxn],r[maxn];bool dfs(int L,int R){    if(L+1>=R)return true;    for(int i=L;i<R;i++)    {//从两边向中间判断        if(l[i]<L&&r[i]>=R)return dfs(L,i)&&dfs(i+1,R);//判断区间左边的元素        if(l[R-(i-L)-1]<L&&r[R-(i-L)-1]>=R)return dfs(L,R-(i-L)-1)&&dfs(R-(i-L)-1+1,R);//判断区间右边的元素    }    return false;}int main(){    int t;    cin>>t;    while(t--)    {        int n;        cin>>n;        for(int i=0;i<n;i++)        {            cin>>a[i];        }        for(int i=0;i<n;i++)        {            pos[i]=-1;        }        for(int i=0;i<n;i++)        {            l[i]=pos[a[i]];//记录它的左边与它相同的数字的最近的位置            pos[a[i]]=i;        }        for(int i=0;i<n;i++)        {            pos[a[i]]=n;        }        for(int i=n-1;i>=0;i--)        {            r[i]=pos[a[i]];//记录它的右边与它相同的数字的最近的位置            pos[a[i]]=i;        }        if(dfs(0,n))cout<<"non-boring"<<endl;        else cout<<"boring"<<endl;    }    return 0;}