1题目内容
1.1 问题描述
给出一个堆栈的输入序列,试判断一个序列是否能够由这个堆栈输出。如果能,返回总的出栈次数,如果不能,返回0。序列的输入及输出都是从左往右。(输入输出序列皆为整数且没有重复的数字,如果一个数字在输入序列中没有出现,那么其在输出序列中也不会出现)
1.2 输入形式
第一行为输入序列的长度,然后为输入序列的数字;第二行为输出序列的数字。输入数据以空格隔开。
1.3 输出形式
如果是一个出栈序列,则返回总的出栈次数, 否则返回0
1.4 样例输入
5 1 2 3 4 5
1 2 3 4 5
1.5 样例输出
5
1.6 样例说明
第一行输入的第一个数字是序列的长度,1 2 3 4 5 输入序列,以空格隔开,输出的总的出栈次数。
2 大致思路
这道题有很多需要注意的地方
首先是读取第二行的输入数据。因为没有给出第二行要有多少输入数据,所以需要写个EOF。
对于解题思路而言,思考几个例子:
5 1 2 3 4 5
4 5 3 2 1
(输出5,1 2 3入栈, 4入栈,4出栈,5入栈,5出栈,3 2 1出栈)
5 1 2 3 4 5
5 1
(输出5, 1 2 3 4 5入栈,5 4 3 2 1出栈,但只取5和1)
5 1 2 3 4 5
4 5 3 1 2
(输出0, 因为1不能在2之前出栈)
第三个例子不能作为输出序列,是因为1出栈前需要2也出栈,但目标序列需要2在1后出栈。(后面还有好多思路,但是我不会讲233)
3 实现代码
#include<stdio.h>
int stack[100+5];
int aimStack[100+5];
int record[100+5];
int find_aim(int a[], int a_length, int aim)
{
int i = 0;
for(i = 0; i < a_length; i++)
{
if(a[i] == aim) return i;
}
return -1;
}
int main(void)
{
int flag = 0;
// input
int n; // stack length
scanf("%d", &n);
int i = 0;
for(i = 0; i < n; i++)
{
scanf("%d", &stack[i]);
}
int m = 0; // aim stack length
while(scanf("%d", &aimStack[m]) != EOF){
m++;
}
// input data end
for(i = 0; i < n ; i++)
{
record[i] = 1;
}
int formerOneIndex = find_aim(stack, n, aimStack[0]);
int currentOneIndex;
record[formerOneIndex] = 0;
for(i = 1; i < m; i++)
{
currentOneIndex = find_aim(stack, n, aimStack[i]);
if(record[currentOneIndex] == 0)
{
flag = 1;
break;
}
if(currentOneIndex > formerOneIndex)
{
record[currentOneIndex] = 0;
formerOneIndex = currentOneIndex;
}
else if(currentOneIndex < formerOneIndex)
{
int j = 0;
for(j = currentOneIndex; j < formerOneIndex; j++)
{
record[j] = 0;
}
}
}
if(flag == 1)
{
printf("0\n");
}
else
{
int num = 0;
for(i = 0; i < n; i++)
{
if(record[i] == 0) num++;
}
printf("%d\n", num);
}
return 0;
}
4 学习后言

这和栈也没太大关系。
617



被折叠的 条评论
为什么被折叠?



