1112 超标区间 - PAT (Basic Level) Practice (中文) (pintia.cn)
思想
可以用模拟做,也可以用双指针做。
模拟
模拟做的话我们直接对读入进行处理,每读入一个数我们就判断它是否大于t值,如果大于我们就将其作为左端点输出,然后给其标记为0,以后再碰见大于t的值如果标记为0就不输出,直到碰见小于t的值之后我们将其作为右端点输出。然后我们需要把标记重新置为1,继续向后遍历,寻找下一段区间,重复上述操作。
这里注意我们要对结尾进行特判,假设最后一个数的值大于t,那么它就是左端点,但是再往后就没有了,也就是说找不到右端点了,因此我们要将最后一个数作为右端点输出。
下面是特判和不特判的情况:
#include<bits/stdc++.h>
using namespace std;
int n,t,flag=1,all=1,maxn;
int main()
{
cin>>n>>t;
for(int i=0;i<n;i++)
{
int x;cin>>x;
maxn=max(maxn,x);
if(x>t)
{
if(flag==1)
{
cout<<"["<<i<<", ";
flag=0;
all=0;
}
}
if(x<=t)
{
if(!flag)
{
cout<<i-1<<"]"<<endl;
flag=1;
}
}
}
//特判
if(!flag)cout<<n-1<<"]"<<endl;
if(all)cout<<maxn<<endl;
return 0;
}
双指针
首先遍历一下数组,如果a[i]>t值的话那么就给当前i位置打上end指针,i作为左端点,end指针向后遍历,直到a[end+1]<t值时此时a[end]就是该区间内最后一个大于t的值,end就是该区间的右端点。
#include<bits/stdc++.h>
using namespace std;
int a[10005];
int main()
{
int n,tol;cin>>n>>tol;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
int maxn=-1;
for(int i=0;i<n;i++)
{
maxn = max(maxn, a[i]);
if(a[i]<=tol)continue;
int end=i;
//当没有走到数组末尾 并且 都是大于tol的情况 end就一直往后走
//当a[end+1]<tol的时候就输出end,即小于tol的前一个大于tol的数
while(end+1<n&&a[end+1]>tol)++end;
cout<<"["<<i<<", "<<end<<"]"<<endl;
i=end; //更新下一个区间左端点的位置
}
if(maxn<=tol)cout<<maxn;
return 0;
}