提示:本文有一点啰嗦
思路:
模拟这个过程,我们拿3 2 4 1 6 5举例
首先pop出去的是3,那么当前栈中剩下的就应该如下
2
1
即从1开始push一直到3,然后就pop掉3了,
好,我们现在看到2, 2比3小,那么必然在栈中,而且一定是位于栈顶
因为我们是不断+1这样叠上去的,所以说一旦pop出来的小于上一个数字,那么他必然是栈的数字中距离上一个数字最近的一个呀,
即3才刚刚pop了出去,接下来要想pop一个比3小的数字,是不是必然要比3小1,即2
也就是说,如果当前数字小于上一个数字,而且要符合栈的pop顺序的话
当前数字与上一个pop出去的数字的值之差应当是最小的,
那么很显然,这个数字一定是在栈顶了,所以2符合题意
那么当前栈中只剩下了1
好,我们再看到4,4比上一个数字2要大,那么正常来说要想pop出来一个4,栈就必须经历过从1到4的push,
那么我们对于之前已经pop出去了的数字,以及已经在栈中的数字,是不是已经没有必要从1开始push,
所以我们定义了一个t数组用于标记该数字是否已经push过或者pop过了,这些数字也就不必再入栈了,(代码中其中t[i]=1表示不必入栈)
注意:下面P=0表示不符合题一,我们不应当在这时候就立刻break出去,因为题目所给的数据需要全部输入
#include<cstdio>
#include<cstring>
#include<stack>
int a[1001],t[1001];
int main()
{
int m,n;
stack<int> s;
scanf("%d%d",&m,&n);
while(n--)
{
int p=1;//默认当前这一组测试数据是符合题意的
memset(a,0,sizeof(a));
memset(t,0,sizeof(t));
for(int i=1;i<=m;i++)
{
scanf("%d",&a[i]);
if(a[i]>a[i-1])//当前数字比上一位大时
{
t[a[i]]=1;//当前pop出来的相当于已经进过栈了
for(int j=1;j<=a[i]-1;j++)//从1遍历到当前
{ //数字的上一个
if(t[j]==0)//从未入过栈
{
s.push(j);
t[j]=1;//入过栈了
}
}
}
else//当前数字比上一位小时
{
if(a[i]!=s.top()) p=0;//不符合题意
else s.pop();//符合题意,模拟pop出去的过程
}
}
if(p)printf("YES\n");
else printf("NO\n");
}
return 0;
}