只有一端开口的瓶子
栈就是像 "只有一端开口的瓶子" 一样的数据结构,大家可以理解为一个头部固定的数组,无论是取出数字还是放入数字,你都只能在数组末尾那一端(称为栈顶)修改。
非常喜欢数据结构的周老师又在给新加入 ACM 俱乐部的小萌新们传授他的人生经验......
这天,周老师得到了一个乱序的全排列,其中 1\cdots n1⋯n 共 nn 个数字,每个数字都恰好只出现一次。但是周老师不喜欢无序的东西,所以他总想要把这个数列弄成一个递增的新数列。但是他现在手里恰好只有一些简单的数据结构—— kk 个栈。这些栈一开始全都为空,周老师想要只通过 33 种操作,把初始的序列变成有序的新序列:
- 取出序列当前的第一个数字,插入到第 pp 个栈的顶部:push p
- 取出第 pp 个栈的顶部数字,插入到新序列的末尾位置:pop p
- 取出第 pp 个栈的顶部数字,插入到第 qq 个栈的顶部:move p q
周老师非常的睿智,他一下就想到了如果持有的栈的个数大等于数字总个数(也就是 k\ge nk≥n),那么一定可以完成这项排序工作。作为本次数据结构专题讲课的作业题,周老师想考考身为小萌新的你,至少需要多少个这样的栈才能把给定的初始序列变成有序的新序列呢?换句话说,周老师想知道 kk 的最小值 \texttt{min}\{k\}min{k} 是多少。
Input
第一行输入一个正整数 T\ (1\le T\le 100)T (1≤T≤100),表示数据组数。接下来 TT 组数据,每组数据均满足:
- 第一行输入一个正整数 n\ (1\le n\le 10^5)n (1≤n≤105),表示本组数据输入的全排列序列长度。
- 第二行输入 nn 个由空格间隔开的正整数 p_1,p_2,\cdots,p_np1,p2,⋯,pn,描述全排列序列 PP 的组成元素。请注意该序列是有顺序的,操作 11 只能从前往后取数字。输入保证 [1,n][1,n] 中每个正整数在 p_1\cdots \ p_np1⋯ pn 中恰好只出现一次。
Output
对于每组数据,请输出一个正整数 kk,表示至少需要 kk 个这样的栈才能把给定的初始序列变成有序的新序列。
Example
Input
3 3 3 2 1 2 1 2 3 2 3 1
Output
1 1 2
代码
#include<bits/stdc++.h>
using namespace std;
int a[100005]={0};
int main(){
ios::sync_with_stdio(false);//可以大幅提高大数据的输入和输出以节省时间
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
stack<int>s;//定义栈
for(int i=1;i<=n;i++){
cin>>a[i];
}
int p=1;
for(int i=1;i<=n;i++){
s.push(a[i]);//将a放入栈中
while(!s.empty()&&s.top()==p)//top取栈顶元素,
//观察栈内是否能顺序全部 取出,不能就需要2个
{//empty()可以检验栈是否为空,为空时为真
p++;
s.pop();//使栈顶元素出栈
}
}
if(s.empty())
puts("1");
else
puts("2");
}//size可确定栈内的元素个数
return 0;
}