在一次考试之后,作为班主任的T老师需要给n个学生改卷子,T老师有个习惯,就是按学号的先后来看卷子,所以T老师每次看卷子之前都需要给卷子排好先后次序再改。
但是因为T老师的空闲时间很短,所以他想尽量把这个排序的任务分成多次来做。因此他请你将卷子分成一小叠一小叠的(但不打乱卷子现有顺序),使得她只需要对每一叠分别排序,就能将整堆卷子排序。
初始的卷子次序为a[i],请问你最多能把卷子分成多少小叠。
保证卷子上面的学号为0...n-1的一个排列。
输入
第一行一个数n;
第二行n个数表示a[i],以空格隔开。
n<=100000
第二行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。
将卷子分成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。
题目解析:因为a为0...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 ",sum); return 0; }
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; }