看试卷

在一次考试之后,作为班主任的T老师需要给n个学生改卷子,T老师有个习惯,就是按学号的先后来看卷子,所以T老师每次看卷子之前都需要给卷子排好先后次序再改。
但是因为T老师的空闲时间很短,所以他想尽量把这个排序的任务分成多次来做。因此他请你将卷子分成一小叠一小叠的(但不打乱卷子现有顺序),使得她只需要对每一叠分别排序,就能将整堆卷子排序。
初始的卷子次序为a[i],请问你最多能把卷子分成多少小叠。
保证卷子上面的学号为0...n-1的一个排列。

输入

第一行一个数n;
第二行n个数表示a[i],以空格隔开。
n<=100000

输出

输出一个数,表示最多分出多少叠卷子。

样例输入 Copy

5
4 3 2 1 0

样例输出 Copy

1

提示

1. 样例解释
将卷子分成2叠或者更多块,都无法得到所需的结果。
例如,分成 [4, 3], [2, 1, 0] ,排序得到的结果是 [3, 4, 0, 1, 2],这不是有序的数组。
2. 数据范围
对于20%的数据,1≤n≤20;
对于53%的数据,1≤n≤1000;
对于60%的数据,1≤n≤2000;
对于100%的数据,1≤n≤100000。
 
题目解析:因为a0...n-1的一个排列。因此,一段区间[i,j]可以单独分块排序,一定满足前j个值为1-j如何快速判断条件是否成立呢?可以通过判断(a_1-a_j)中的最大值是否为j来做,因此只要记录前缀最大值就好,复杂度O(n)
AC代码:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
inline int read() {int x=0,f=1;char c=getchar();while(c!='-'&&(c<'0'||c>'9'))c=getchar();if(c=='-')f=-1,c=getchar();while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();return f*x;}
typedef long long ll;
const int maxn = 1e5+10;
int main()
{
    int t,h;
    cin>>t;
    int ans,sum=0;
    for(int i=0;i<t;i++){
        cin>>h;
        ans=max(ans,h);
        if(ans==i){
            sum++;
        }
    }
    printf("%d\n",sum);
    return 0; 
}
View Code

AC代码2:

#include <bits/stdc++.h> using namespace std;
int main() 
{
    int n,max=0,ans=0,num; 
    cin>>n;
    for(int i = 0; i < n; i++){ 
        cin>>num;
        max = max > num ? max : num; 
        ans += max == i;
    }    
    cout << ans << endl; 
    return 0;
}
View Code

 

posted @ 2020-01-09 08:45  哎呦哎(iui)  阅读(273)  评论(0编辑  收藏  举报