题目来源:http://ac.jobdu.com/problem.php?pid=1512
-
题目描述:
-
用两个栈来实现一个队列,完成队列的Push和Pop操作。
队列中的元素为int类型。
-
输入:
-
每个输入文件包含一个测试样例。
对于每个测试样例,第一行输入一个n(1<=n<=100000),代表队列操作的个数。
接下来的n行,每行输入一个队列操作:
1. PUSH X 向队列中push一个整数x(x>=0)
2. POP 从队列中pop一个数。
-
输出:
-
对应每个测试案例,打印所有pop操作中从队列pop中的数字。如果执行pop操作时,队列为空,则打印-1。
-
样例输入:
-
3 PUSH 10 POP POP
-
样例输出:
-
10 -1
首先交代一下两个栈s1、s2的含义,栈s1是用于提供入队的,s2是提供出队的。
方法一、如果操作是PUSH时,(1)栈s2非空,那么就要把栈s2中的元素压入栈s1中,然后再读取将被PUSH的数据iData,并把它压入s1中,(2)栈s2为空,那么就可以直接读取被PUSH的数据iData,并把它压入s1中。如果两个栈都为空,那么POP时,只有打印"-1",否则就要把栈s1中的元素倒入栈s2中,留下栈s1中的一个数据然后直接弹出栈s1中的元素,这样减少一次操作(压入栈s2的操作),如果接下来是一系列的POP操作,那么就可直接弹出s2的栈顶元素,然后如果是PUSH,那么再把栈s2中的元素全部倒入栈s1中,然后读取数据并把它压入s1中,这是一个一般的想法。
方法二、方法一可以优化一下,这个优化是:如果操作是PUSH,那么直接读取数据并把它压入s1中,如果操作是POP,并且s2非空,那么就可直接弹出栈s2的栈顶元素,无需管s1是否为空,仔细考虑考虑,其实就是利用了栈的性质。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
using namespace std;
const int MAXN = 100010;
int main()
{
stack <int> s1;
stack <int> s2;
int n, Len, iData;
char str[6];
while(~scanf("%d", &n))
{
scanf("%s", str);
if(str[1] == 'U')//push
{
scanf("%d", &iData);
s1.push(iData);
continue ;
}
if(!s2.empty())//栈s2非空,那么直接弹出栈顶元素
{
printf("%d\n", s2.top());
s2.pop();
continue ;
}
if(s1.empty())//到此,说明s2栈空,如果s1也是栈空,那么说明没有元素,打印“-1”
{
printf("-1\n");
continue ;
}
Len = s1.size();//到此说明s2栈空,栈s1非空,那么就要把栈s1中的元素倒入s2中,不用倒完,留下s1中一个元素,直接弹出
while(Len > 1)
{
s2.push(s1.top());
s1.pop();
Len--;
}
printf("%d\n", s1.top());
s1.pop();
}
return 0;
}