2020年PAT春考B-2 超标区间 题型:模拟,双指针 分值:20分

75 阅读2分钟

1112 超标区间 - PAT (Basic Level) Practice (中文) (pintia.cn)

思想

可以用模拟做,也可以用双指针做。

模拟

模拟做的话我们直接对读入进行处理,每读入一个数我们就判断它是否大于t值,如果大于我们就将其作为左端点输出,然后给其标记为0,以后再碰见大于t的值如果标记为0就不输出,直到碰见小于t的值之后我们将其作为右端点输出。然后我们需要把标记重新置为1,继续向后遍历,寻找下一段区间,重复上述操作。

这里注意我们要对结尾进行特判,假设最后一个数的值大于t,那么它就是左端点,但是再往后就没有了,也就是说找不到右端点了,因此我们要将最后一个数作为右端点输出。

下面是特判和不特判的情况:

image.png image.png

#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;
}

image.png

双指针

首先遍历一下数组,如果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;
}

image.png