-(https://www.luogu.com.cn/problem/P4387)
题目描述
给出两个序列 pushed 和 poped 两个序列,其取值从 1 到 n(n≤100000)。已知入栈序列是 pushed,如果出栈序列有可能是 poped,则输出 Yes
,否则输出 No
。为了防止骗分,每个测试点有多组数据。
输入格式
第一行一个整数 q,询问次数。
接下来 q 个询问,对于每个询问:
第一行一个整数 n 表示序列长度;
第二行 n 个整数表示入栈序列;
第三行 n 个整数表示出栈序列;
输出格式
对于每个询问输出答案。
输入 #1 输出 #1
2 Yes 5 No 1 2 3 4 5 5 4 3 2 1 4 1 2 3 4 2 4 1 3
解题思路
该题实际为判断出栈序列是否合法,可以通过数组模拟入栈和出栈过程进行解题;
具体步骤:
1.创建辅助栈和一个指向入栈序列 pushed 的指针 ,初始时指向入栈序列的第一个元素。
2.遍历出栈序列 poped 的每个元素,对于当前元素 poped[i],若栈顶元素等于 poped[i],则执行出栈操作,即将栈顶元素弹出,同时 i 指向下一个元素。反之则执行入栈操作,即将入栈序列 pushed 中指针指向的元素压入栈中,且将指针后移一位。
3.在遍历完出栈序列 poped 后,如果辅助栈中的元素已经全部出栈,说明出栈序列 poped 可能是由入栈序列 pushed 经过一系列入栈和出栈操作得到的,输出 Yes;否则输出 No。
代码示例
#include <stdio.h>
int a[100002];
int b[100002];
int c[100002];//辅助栈
int main() {
int q;
scanf("%d", &q);
while(q--) {
int n = 0;
scanf("%d", &n);
for(int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
for(int i = 0; i < n; i++) {
scanf("%d", &b[i]);
}
int tb = 0, tc = 0;
for(int i = 0; i < n; i++) {
c[tc] = a[i];//push
while(b[tb] == c[tc] && tc > -1 && tb != n) {//遍历出栈序列是否有元素与辅助栈栈顶元素相同
tc--;//相同则弹出
tb++;
}
tc++;
}
if(tc == 0) printf("Yes\n");
else printf("No\n");
}
return 0;
}