题目描述
给出两个序列 pushed 和 poped 两个序列,其取值从 1 到 n(n\le100000)n(n≤100000)。已知入栈序列是 pushed,如果出栈序列有可能是 poped,则输出
Yes
,否则输出No
。为了防止骗分,每个测试点有多组数据。输入格式
第一行一个整数 qq,询问次数。
接下来 qq 个询问,对于每个询问:
第一行一个整数 nn 表示序列长度;
第二行 nn 个整数表示入栈序列;
第三行 nn 个整数表示出栈序列;
输出格式
对于每个询问输出答案。
输入输出样例
输入 #1复制
2 5 1 2 3 4 5 5 4 3 2 1 4 1 2 3 4 2 4 1 3输出 #1复制
Yes No
1.这是一道有关数据结构——栈的知识的题目。
2.刚开始一看以为是只要判断是否俩个成为逆序的数组就可以,但是代码AC不过,我后面也觉得只是这样确实是简单了。后面转念一想,有可能是 它中途出栈,后面又入栈。应该要我们判别的是这个。
3.这道题应该先保存这俩个入栈和出栈的数组,题目中有提到过,它的取值从1到n,是没有重复的数字的。所以我们就需要模拟出入栈。
4.栈是先入后出,我们要按照出栈的顺利来出栈,如果还没遇到该出栈的数字,我们就需要先入栈,就是在C里面去存入a对应的值,如果遇到了b数组的值,就开始在c数组里面出栈,其实就是c.top--咯,b数组往后走,要一直出栈直到,c数组与b数组没有相等的元素。什么时候结束这些操作呢,就是a数组入栈入完了即可。
5.输出Yes或者No是要看,c数组是否模拟出入栈完了,也就是说c.top<=1(我这边初始值是1),说明它能按照b数组出栈成功,所以b数组是一个正确的出栈顺序。否则就不是。
代码如下:
#include<stdio.h>
#define N 100000+10
struct stack
{
int x[N];
int top;
}a,b,c;
int main()
{
int t,n,i;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a.x[i]);
for(i=0;i<n;i++)
scanf("%d",&b.x[i]);
a.top=b.top=0;c.top=1;
while(a.top<n)
{
c.x[c.top]=a.x[a.top];
while(b.x[b.top]==c.x[c.top])
{
b.top++;c.top--;
}
c.top++;a.top++;
}
if(c.top<=1) printf("Yes\n");
else printf("No\n");
}
}