栈和队列(习题)

回文(栈和队列)

Description

假设称正读和反读都相同的字符序列为“回文”,例如,‘abba‘ 和 ‘abcba‘是回文,‘abcde‘ 和 ‘ababab‘ 则不是回文。试写一个算法判别读入的一个以‘@‘为结束符的字符序列是否是“回文”。

Input

abcba

Output

是回文

Sample Input

ababab

Sample Output

不是回文


很简单的栈和队列练习题,在了解栈的原理后很容易就可以做出来,我们直接上代码。

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <stack>
using namespace std;
int main()
{
    stack <int> s1,s2;
    int n=0,i,l;
    char ch1[1000],ch2[1000];
    gets(ch1);
    l=strlen(ch1);
    for(i=0;i<l;i++)
    {
        ch2[l-1-i]=ch1[i];
    }
    for(i=0;i<l;i++)
    {
        s1.push(ch1[i]);
        s2.push(ch2[i]);
    }
    for(i=0;i<l;i++)
    {
        if(s1.top()==s2.top())
        {
            s1.pop();
            s2.pop();
        }

    }
    if(s1.empty()!=0)
        printf("是回文\n");
    else
        printf("不是回文\n");
    return 0;

}

B - 出栈序列(栈和队列)

Description

已知自然数1,2,...,N(1≤N≤10000)依次入栈(即a<b当且仅当a先于b入栈),问:序列C1,C2,...,CN是否为可能的出栈序列。例如:N=5时,3,4,2,1,5是一个可能的出栈序列,因为其可以按如下操作获得:push 1,push 2,push 3,pop,push 4,pop,pop,pop,push 5,pop。

Input

 输入数据包含若干组测试样例。
  每组测试样例的第一行为整数N(1≤N≤10000);
  第二行为N个正整数,以空格隔开,为出栈序列;
  输入数据的末尾以一个0表示输入的结束。

Output

对于每组测试样例,输出结果为一行字符串。
  如给出的序列是可能的出栈序列,则输出”Yes”,否则输出”No”。
  注意:区分大小写,引号本身不输出。

Sample Input

5
3 4 2 1 5
5
3 5 1 4 2
0

Sample Output

Yes
No

我在博客园中已经写过这个题了,此处直接粘过来
题意有点不好理解,我们说一下此题的样例来理解题意

首先有5个数入栈,出栈序列数也为5个,我们把1 2 3 4 5依次入栈,并同时判断是否出栈
首先1入栈,出栈队列第一个为3,不相等,故1在栈中不动;
然后2入栈,栈首2依然不等于3,故2在栈中不动;
然后3入栈,此时栈首3与出栈序列第一个相等,3出栈;
再次比较,此时栈首为2,与出栈序列第二个不相等,2在栈中不动;
然后4入栈,此时栈首4与出栈序列第二个相等,4出栈;
再次比较,此时栈首为2,与出栈序列第三个相等,2出栈;
再次比较,此时栈首为1,与出栈序列第四个相等,1出栈;
此时栈为空,5入栈,与出栈序列第五个相等,5出栈;
至此,栈中元素全部弹出,故给出的序列为可能的出栈序列。

按照上面的思路,大家可以试一试第二个样例。

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <stack>
using namespace std;
int main()
{
    int N;
    while(scanf("%d",&N)!=EOF&&N)
    {
        stack <int> s1,s3;
        int s2[15000];
        int d=2,i,flag=0;
        for(i=1;i<=N;i++)
            scanf("%d",&s2[i]);
        for(i=N;i>=1;i--)
            s1.push(s2[i]);
        s3.push(1);
        while(1)
        {
            if(s3.top()==s1.top())
            {
                s1.pop();
                s3.pop();
            }
            if(s1.empty()&&s3.empty())
            {
                flag=1;
                break;
            }

            if(s3.empty())
                s3.push(d++);
            else if(s3.top()!=s1.top())
                s3.push(d++);
            if(d==N+2)
                    break;
        }
        if(flag)
            printf("Yes\n");
        else
            printf("No\n");
    }
}

C - 括号匹配(栈和队列)

Description

假设一个算术表达式中可以包含三种括号:圆括号“(”和“)”,方括号“[”和“]”和花括号“{”和“ ”,且这三种括号可按任意的次序嵌套使用(如:…[…{… …[…]…]…[…]…(…)…)。编写判别给定表达式中所含括号是否正确配对出现的算法。输出结果YES 或者 NO。

Input

5+{[2X5]+2}

Output

YES

Sample Input

8-[{2+7]}

Sample Output

NO

思路很简单,我们通过两个栈来判断,一个存左括号一个存右括号,
由于栈的特性,栈首肯定是当前最优先匹配的括号,也就是最内部的括号,
通过这样的比较,如果两栈都空了,那么自然括号全部匹配了;
否则,有可能是左括号和右括号数量不相等,或者,某处括号未能匹配。

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <stack>
#include <string.h>
using namespace std;
int main()
{
    stack <char> s1,s2;
    char c,t;
    int i,k,l;
    char ch[2000];
    gets(ch);
    l=strlen(ch);
    for(i=l-1;i>=0;i--)//如果是括号那么就入栈,不是括号就不要;
    {
        if(ch[i]=='('||ch[i]==')'||ch[i]=='['||ch[i]==']'||ch[i]=='{'||ch[i]=='}')
            s1.push(ch[i]);

    }
    k=s1.size();
    for(i=0;i<k;i++)//然后我们遍历一遍栈中的元素;
如果是左括号,那么我们把他放入另外一个栈中;
    {
        t=s1.top();
        if(t=='('||t=='['||t=='{')
        {
            c=s1.top();
            s1.pop();
            s2.push(c);
        }
        else if((s2.top()=='('&&s1.top()==')')||(s2.top()=='['&&s1.top()==']')||(s2.top()=='{'&&s1.top()=='}'))
        //然后我们判断两个栈中栈首,如果匹配,同时出栈;
        {
            s2.pop();
            s1.pop();
        }
    }
    if(s2.empty()&&s1.empty())
        printf("YES\n");
    else
        printf("NO\n");
    return 0;
}

D - 求子数组的最大和(栈和队列)

Description

题目:输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。
例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,
因此输出为该子数组的和18。

Input

1 -2 3 10 -4 7 2 -5

Output

18

Sample Input

1 -2 3 10 -4 7 2 -5

Sample Output

18

我们先来一个数组模拟的代码,在介绍一个用队列实现的代码。

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <stack>
#include <queue>
using namespace std;
#define inf 0x3f3f3f3f
int main()
{
   // freopen("d:\\in.txt","r",stdin);
    int n[2000];
    int i,l=0,sum=0;
    int tt=4,maxm=-inf,maxn=-inf;
    char ch;
    while(ch!='\n')
    {
        scanf("%d",&n[l++]);
        ch=getchar();
    }
    for(i=0;i<l;i++)
    {
        sum+=n[i];
        if(sum<0)
            sum=0;
        maxm=max(maxm,sum);
        maxn=max(maxn,n[i]);
    }
    if(maxm==0)
        printf("%d",maxn);
    else
        printf("%d",maxm);
    return 0;
}

队列:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <stack>
#include <queue>
using namespace std;
#define inf 0x3f3f3f3f
int main()
{
    //freopen("d:\\in.txt","r",stdin);
    queue <int> que;
    int n;
    int i,sum=0;
    int maxm=-inf,maxn=-inf;
    char ch;
    while(ch!='\n'&&scanf("%d",&n)!=EOF)
    {
        que.push(n);
        ch=getchar();
    }
    for(i=0;!que.empty();i++)
    {
        int k=que.front();
        sum+=k;
        if(sum<0)
            sum=0;
        maxm=max(maxm,sum);
        maxn=max(maxn,k);
        que.pop();
    }
    if(maxm==0)
        printf("%d",maxn);
    else
        printf("%d",maxm);
    return 0;
}

栈和队列的介绍暂时到此为止
后面会继续补充关于单调队列和优先队列的讲解和题目
所有关与栈和队列的题目和讲解都会放在栈和队列分类中
如果发现错误望各位dalao给予指正

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值