[洛谷]【深基15.习9】验证栈序列
一、题目描述
题目描述
给出两个序列 pushed 和 poped 两个序列,其取值从 1 到
n
(
n
≤
100000
)
n(n\le100000)
n(n≤100000)。已知入栈序列是 pushed,如果出栈序列有可能是 poped,则输出 Yes
,否则输出 No
。为了防止骗分,每个测试点有多组数据。
输入格式
第一行一个整数 q q q,询问次数。
接下来 q q q 个询问,对于每个询问:
第一行一个整数 n n n 表示序列长度;
第二行 n n n 个整数表示入栈序列;
第三行 n n n 个整数表示出栈序列;
输出格式
对于每个询问输出答案。
样例 #1
样例输入 #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、思路分析
我们想要判断一个序列是不是合法的出栈序列,我们就需要先去搞明白一个元素从栈中出来需要满足什么要求。
很明显,只有栈顶的元素才能够出栈,如果我们想要出栈的元素不在栈顶的位置,那么此时我们就能够判断这个序列是不合法的。
因此,我们去遍历出栈序列。
我们假设这个出栈序列是合法的。
如果,当前所遍历到的元素不在栈顶的位置,而这个序列又是合法的,那么只有一种情况,就是这个元素不在栈内。所以,我们需要将入栈序列不断地入栈,直到我们想要出栈的那个元素到达了栈顶。
如果说,我们将整个入栈序列都加进去了,我们想要的元素依旧没有出现,那么只能说明我们想要出栈的元素本身就在栈里,只不过它不是栈顶,那么它不可能优先出栈,也就是说我们的假设不成立,也就说明此时的出栈序列是不合法的。
三、代码实现
#include<iostream>
#include<stack>
#include<vector>
using namespace std;
vector<int>v1,v2;
stack<int>stk;
int n,m,a;
int main()
{
cin>>n;
while(n--)
{
cin>>m;
for(int i=0;i<m;i++)
{
scanf("%d",&a);
v1.push_back(a);
}
for(int i=0;i<m;i++)
{
scanf("%d",&a);
v2.push_back(a);
}
bool flag=true;
int k=0;
for(int i=0;i<m;i++)
{
if (stk.empty())stk.push(v1[k++]);
while(stk.top()!=v2[i]&&k<=m)stk.push(v1[k++]);
if(stk.top()!=v2[i])
{
flag=false;
break;
}
else stk.pop();
}
if(flag)puts("Yes");
else puts("No");
v1.clear();
v2.clear();
}
return 0;
}