Mandel520 @ 2022-02-10 12:03:00
下面这个是我使用stack并成功AC的程序:
#include<bits/stdc++.h>
using namespace std;
int q, n; //q:询问次数 n:序列长度
int input_arr[100005]; //入栈序列
int output_arr[100005]; //出栈序列
int main(){
cin >> q;
while(q--){
cin >> n;
for (int i = 1; i <= n; i++) cin >> input_arr[i]; //入栈序列
for (int i = 1; i <= n; i++) cin >> output_arr[i]; //出栈序列
stack<int> s;
int idx1 = 1; //表示当前入栈序列匹配的位数
int idx2 = 1; //表示当前出栈序列匹配的位数
while (idx2 <= n){
while((s.empty()) || (s.top() != output_arr[idx2])){//栈顶和出栈序列不相同则继续入栈
if(idx1 > n){ //全都入栈了还是不能匹配出栈序列
cout << "No" << endl;
goto part1;
}
s.push(input_arr[idx1]); //入栈
idx1++;
}
while((!s.empty()) && s.top() == output_arr[idx2] && idx2 <= n){//栈顶和出栈序列相同则出栈
s.pop(); //出栈
idx2++;
}
}
cout << "Yes" << endl;
part1:;
}
return 0;
}
下面这个是我手写栈的程序,思路和上面的程序相同, 但是TLE了4个点
#include<stdio.h>
#include<string.h>
typedef struct{ //定义栈
int Data[100005]; //存储元素的数组
int topIdx; //栈顶指针
}Stack;
void InitStack(Stack *s){ // 初始化栈
s->topIdx = 0;
memset(s->Data, 0, sizeof(s->Data));
}
int Push(Stack *L, int e){ //将元素推入栈中
if (L->topIdx == 100005 - 1) return 0; //栈已满
L->Data[L->topIdx++] = e; //加入栈中
return e; //返回压入的元素
}
int Pop(Stack *L){ //移除栈顶元素
if (L->topIdx == 0) return 0;
int val = L->Data[--(L->topIdx)];
//printf("%d ",val);
return val;
}
int Top(Stack s){ //返回栈顶元素
if (s.topIdx == 0) return 0;
return s.Data[s.topIdx - 1];
}
int isEmpty(Stack s){ //判断栈s是否为空
if (s.topIdx == 0) return 1;
return 0;
}
int isFull(Stack s){ //判断栈是否已满
if (s.topIdx != 100005 -1) return 1;
return 0;
}
int q, n; //q:询问次数 n:序列长度
int input_arr[100005]; //入栈序列
int output_arr[100005]; //出栈序列
int main(){
scanf("%d", &q);
while(q--){
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &input_arr[i]); //入栈序列
for (int i = 1; i <= n; i++) scanf("%d", &output_arr[i]); //出栈序列
Stack s;
InitStack(&s);
int idx1 = 1; //表示当前入栈序列匹配的位数
int idx2 = 1; //表示当前出栈序列匹配的位数
while(idx2 <= n){
while((isEmpty(s)) || (Top(s) != output_arr[idx2])){//栈顶和出栈序列不相同则继续入栈
if (idx1 > n){
puts("No");
goto part1;
}
Push(&s, input_arr[idx1]); //入栈
idx1++;
}
while((!isEmpty(s)) && Top(s) == output_arr[idx2] && idx2 <= n){//栈顶和出栈序列相同则出栈
Pop(&s); //出栈
idx2++;
}
}
puts("Yes");
part1:;
}
return 0;
}
现在我需要指出的是:
(1)这个手写的栈, 之前已经在P1241和P1449两道题中使用过, 所以应该不是手写的栈的问题
(2)下面这个程序中的main()函数和上面的程序中的main()函数几乎完全一致, 因此也不想是main()函数中的问题
(3)讨论区的所有hack样例我全都使用第二个程序测过了, 全都通过. 说明也不是犯了其他人犯过的错误
(4)因为是数组实现的栈, 因此时间复杂度本身是没有问题的
基于以上4点, 我实在想不通第二个程序的问题出在哪, 因此恳求各位大佬帮我看看
by yukimianyan @ 2022-02-10 13:19:21
@Jeremy_Mandel 是您的手写栈实现不好
int Top(Stack s){ //返回栈顶元素
if (s.topIdx == 0) return 0;
return s.Data[s.topIdx - 1];
}
int isEmpty(Stack s){ //判断栈s是否为空
if (s.topIdx == 0) return 1;
return 0;
}
int isFull(Stack s){ //判断栈是否已满
if (s.topIdx != 100005 -1) return 1;
return 0;
}
这些函数传参传的是 Stack s
,每次调用都会复制一个新的 Stack
,一共调用 1e5 次,每次复制 1e5 级别的内存,常数爆炸,建议传指针或者引用
by yukimianyan @ 2022-02-10 13:19:50
int Top(Stack &s){ //返回栈顶元素
if (s.topIdx == 0) return 0;
return s.Data[s.topIdx - 1];
}
int isEmpty(Stack &s){ //判断栈s是否为空
if (s.topIdx == 0) return 1;
return 0;
}
int isFull(Stack &s){ //判断栈是否已满
if (s.topIdx != 100005 -1) return 1;
return 0;
}
by Mandel520 @ 2022-02-10 14:45:17
@yukimianyan 谢谢大佬, 大佬太强了, 已经关注大佬了