Sound静音问题(bzoj1342)

问题 C: Sound静音问题(bzoj1342)
时间限制: 1 Sec 内存限制: 128 MB
提交: 116 解决: 38
[提交][状态]
题目描述
数字录音中,声音是用表示空气压力的数字序列描述的,序列中的每个值称为一个采样,每个采样之间间隔一定的 时间。 很多声音处理任务都需要将录到的声音分成由静音隔开的几段非静音段。为了避免分成过多或者过少的非 静音段,静音通常是这样定义的:m个采样的序列,该序列中采样的最大值和最小值之差不超过一个特定的阈值c。 请你写一个程序,检测n个采样中的静音。
输入
第一行有三个整数n,m,c,分别表示总的采样数、静音的长度和静音中允许的最大噪音程度。 第2行n个整数ai,表示声音的每个采样值,每两个整数之间用空格隔开。 1<=n<=1000000,1<=m<=10000,0<=c<=10000 0<=ai<=1,000,000
输出
列出了所有静音的起始位置i i满足max(a[i, . . . , i+m−1]) − min(a[i, . . . , i+m−1]) <= c 每行表示一段静音的起始位置,按照出现的先后顺序输出。 如果没有静音则输出NONE。
样例输入
7 2 0

0 1 1 2 3 2 2
样例输出
2

6
林肯是大头:
http://www.accoders.com/problem.php?cid=1965&pid=2
bzoj
https://www.lydsy.com/JudgeOnline/problem.php?id=1342
单调队列模板题。。。竟然还卡住了
思路:维护一段长为M的区间,使区间中最大值最小值之差不大于C。。。
思路完事,实现出现一些问题。。。
单调队列实际上应该就是维护一段移动连续的区间最大最小值,所以区间的长度其实就是限制队尾的条件,与入队一样放在相同位置维护。
而题目的一些条件就是放在这些操作之后了吧。
注意:
1.单调队列易错点:忽略队首队尾关系,一定要限制!
2.加入第一个数时可以不用虚拟节点,而是进行Tail=1,Head=0的赋值,利用队首队尾关系让出队判断略过

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1000000+10;
int a[maxn];
int qmax[maxn];
int h1=1,t1=0;
int qmin[maxn];
int h2=1,t2=0;
int pos=1;
int main()
{
    int n,m,c;
    bool b=0;
    scanf("%d%d%d",&n,&m,&c);//MAX-MIN不超过C的M个数的序列 
    for(int i=1;i<=n;i++)
    scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)
    {
         
         while(i-qmax[h1]>=m&&h1<=t1) h1++;//i到队尾下标差不超过M 
         while(i-qmin[h2]>=m&&h2<=t2) h2++;
         while(a[qmax[t1]]<a[i]&&h1<=t1) t1--;//入队前的出队操作
         while(a[qmin[t2]]>a[i]&&h2<=t2) t2--;
         //注意所有的队首都要不超过队尾
         qmax[++t1]=i;
         qmin[++t2]=i;
        // printf("i%d pos%d\n",i,pos);
        // printf("len:%d %d\n",t1-h1+1,t2-h2+1);
        // printf("h1:%d %d h2:%d %d\n",h1,a[qmax[h1]],h2,a[qmin[h2]]);
        // printf("t1:%d %d t2:%d %d\n",t1,a[qmax[t1]],t2,a[qmin[t2]]);
         if(i>=m&&a[qmax[h1]]-a[qmin[h2]]<=c) printf("%d\n",i-m+1),b=1;   
         //i的位置显然至少要在M后,并且此时再判断最大值最小值之差     
    }
    if(!b) printf("NONE");
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值