题目描述:
给出一个最多能放M个数的栈,给出一定的序列,序列有N个数,从1到N。再给出一个序列,要求判断这个序列是不是可以从输入序列压栈出栈后得到的序列。
输入:
M N K 栈的大小 序列长度 要检查的输出序列的个数
K 个输出序列
输出
YES NO (全部都是大写啊,别忘了)
#include <iostream>
#include <stack>
using namespace std;
int main()
{
int m,n,k;
scanf("%d %d %d",&m,&n,&k);
while(k--)
{
stack<int> s;
int num = 1;
int goal[n];
for(int i =0; i < n ; ++i)
scanf("%d",&goal[i]);
int index = 0;
while(num <= n)
{
if(num == goal[index])//如果这个可以直接出来 就直接出来
{
num++;
index++;
while(!s.empty())
if(s.top() == goal[index])
{
s.pop();
index++;
}
else
break;
}
else
if((int)s.size() < m-1)//压栈
{
s.push(num);
num++;
}else
break;
}
if(index < n-1)
printf("NO\n");
else
printf("YES\n");
}
return 0;
}
以下为我自己写这个题目的碎碎念,可以跳
//此处为我之前的写的代码 不记得是哪个实验集了
//在写代码之前稍微分析一下问题
//找出yes 对应的情况与no对应的情况 这个比写代码更重要
//按我现在的思路就是从给定的顺序开始遍历
//遇到一个数据 把它前面数据输入到栈里面
//然后再到他这个数据之后去看看前面的数据能否满足条件 如果满足就可以继续这样做直到不满足或者栈空
//但是总感觉这样会遇到问题
//这种情况下对应的yes 就是能够顺利遍历完我的结果数组 不然就可以判定为失败
//换句话说 就是只有在我遍历完这个数组的情况下才能是yes 其他情况直接没
/2021/9/29感觉没有表示清楚我自己的意思 这是这个地方我又加上的自己的理解
判断出栈队列的合法性 已知入栈队列的顺序 又栈只能从上边出去
所以我就利用了一个栈去进行适当的模拟出栈的过程
从出栈队列开始遍历 读取元素 首先看看是不是我们放进去顺序所需要的那个
如果不是 则将其压栈 如果栈已经满了 则说明无法满足需求的条件,可以直接跳出循环 判断失败
如果是,就直接进行下一次移动 但是这不是用的循环 是用while的感觉表达for的意思
下一次的先看看 栈里面的元素能不能满足需求 不能就压栈 能就进行下一次遍历 最后判断是不是所有的需要的元素是不是查完了
如果循环做完了 肯定是查完了,如果因为中途的情况 肯定是不行
这题还可以拓展嘿嘿 比如就是要输出yes的栈的操作顺序/
正经点分析
我采取的是逆向思路。如果从正向压栈能得得到和输出无差的序列,就能判断这个是能达到。
对于输入序列和要判断的序列,其实就两种情况。
当前的元素相同,当前的元素不相同。
当前元素不相同,就把这个输入序列的元素压栈。
当前元素相同,由于栈是逆序的,LIFO,在给定前面的一定在栈里面在底下,所以这时候就从给定的输出序列从前往后找,其实就是在那个栈里面,从下往上找。一直找到两个元素不相同即可。
具体编程
我采用两个指针,一个指针用于输入的那个计数,一个用于对给定的输出序列进行访问。
由于输入的其实是有规律的,我们并不需要真的用数组去存储,用这个数据结构的逻辑就能解决。
对于另一个要判断的,则需要我们真的开一个数组去存放。
在输入数据没有走完的情况下
对于相等的情况
两个指针后移
当我们开辟的存储输入序列的那个栈不空时并且栈顶元素与给定的输出序列的元素一直时,弹出,输出序列的指针后移。
对于不相等的情况
在栈不满的情况下
压栈
否则
可判断为NO
裁定条件:


231

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



