Description
数字录音中,声音是用表示空气压力的数字序列描述的,序列中的每个值称为一个采样,每个采样之间间隔一定的
时间。 很多声音处理任务都需要将录到的声音分成由静音隔开的几段非静音段。为了避免分成过多或者过少的非
静音段,静音通常是这样定义的:m个采样的序列,该序列中采样的最大值和最小值之差不超过一个特定的阈值c。
请你写一个程序,检测n个采样中的静音。
Input
第一行有三个整数n,m,c,分别表示总的采样数、静音的长度和静音中允许的最大噪音程度。
第2行n个整数ai,表示声音的每个采样值,每两个整数之间用空格隔开。
1<=n<=1000000,1<=m<=10000,0<=c<=10000
0<=ai<=1,000,000
Output
列出了所有静音的起始位置i
i满足max(a[i, . . . , i+m−1]) − min(a[i, . . . , i+m−1]) <= c
每行表示一段静音的起始位置,按照出现的先后顺序输出。
如果没有静音则输出NONE。
Sample Input
7 2 0
0 1 1 2 3 2 2
Sample Output
2
6
这道题直接两个单调队列分别维护区间最小值最大值即可,下面是程序:
#include<stdio.h>
#include<iostream>
using namespace std;
const int N=1000005;
struct queue{
int l,r,a[N];
void clear(){
l=0,r=1;
}
bool empty(){
return l+1==r;
}
void push_front(int &x){
a[l]=x;
l=(l+N-1)%N;
}
void push_back(int &x){
a[r]=x;
r=(r+1)%N;
}
void pop_front(){
l=(l+1)%N;
}
void pop_back(){
r=(r+N-1)%N;
}
int front(){
return a[(l+1)%N];
}
int back(){
return a[(r+N-1)%N];
}
};
queue q1,q2;
int a[N],n,m,k;
inline void read(int &s){
s=0;
char c=getchar();
while(c<'0'||c>'9'){
c=getchar();
}
while(c>='0'&&c<='9'){
s=(s<<3)+(s<<1)+c-'0';
c=getchar();
}
}
int main(){
int i;
bool f=1;
read(n);
read(m);
read(k);
q1.clear();
q2.clear();
for(i=1;i<=n;i++){
read(a[i]);
while(q1.front()<=i-m&&!q1.empty()){
q1.pop_front();
}
while(q2.front()<=i-m&&!q2.empty()){
q2.pop_front();
}
while(a[q1.back()]<=a[i]&&!q1.empty()){
q1.pop_back();
}
while(a[q2.back()]>=a[i]&&!q2.empty()){
q2.pop_back();
}
q1.push_back(i);
q2.push_back(i);
if(i>=m&&a[q1.front()]-a[q2.front()]<=k){
printf("%d\n",i-m+1);
f=0;
}
}
if(f){
puts("NONE");
}
return 0;
}
浙公网安备 33010602011771号