2021-12-4 学习的打卡学习第十二天(关于栈的一些题)

本文介绍了如何使用C++中的栈来解决两个算法问题:一是计算奶牛能看到的发型数量,二是判断括号序列是否满足配对条件。通过对比不同实现方式(包括未使用栈、使用栈但超时、以及使用C++标准库栈)的性能,展示了栈在算法中的高效应用。同时,提出了动态规划和双指针作为未来学习的方向。
摘要由CSDN通过智能技术生成

今天刷了道栈算法的题目,然后理解了c++中一些与栈相关的函数。它需要头文件#include<stack>

用法如下:

stack<int> S;//声明一个对象

S.empty();//栈空返回true 否则false

int x=S.size();//返回栈中元素个数于x

S.pop();//移除栈顶元素

S.push(x);将x置于栈顶

x=S.top();返回栈顶元素

文章转载于:https://blog.csdn.net/qq_24286723/article/details/50037479?locationNum=1&fps=1

例题:

Farmer John的奶牛在风中凌乱了它们的发型……
每只奶牛都有一个身高hi(1 ≤ hi ≤ 1,000,000,000),现在在这里有一排全部面向右方的奶牛,一共有N只(1 ≤ N ≤ 80,000)。对于奶牛i来说,如果奶牛i+1,i+2,……,N这些奶牛的身高严格小于奶牛i,则奶牛i可以看到它们凌乱的发型。
比如下面这个例子:

* * * * = *
= * * * = *
= * - * = * 奶牛面向这边-->
= * = * = *
= - = = = *
= = = = = =
1 2 3 4 5 6
('*'表示空的,这是译者为了格式特意弄的,原题没有)

令ci表示第i只奶牛能够看到的发型数量,请计算c1 + c2 + c3 + … + cN的值
对于上面这个例子,答案为3 + 0 + 1 + 0 + 1 + 0=5。

输入

第一行:奶牛数量N
第二到N+1行:第i+1行输入奶牛i的身高

输出

第一行:一个整数即c1到cN的和

样例输入

6
10
3
7
4
12
2

样例输出

5

代码1(没有用栈,时间超过2000ms)

#include<stdio.h>
#define N 1000000
int a[N]={0};
int main()
{
    long long int n,i=0,r=0,c,z=0;
    scanf("%lld",&n);
    for(i=0;i<n;i++)
    scanf("%lld",&a[i]);
    for(i=0;i<n-1;i++)
    {
        c=a[i+1];
        if(a[i]>c)
            z++;
        for(r=i+1;r<n;r++)
        {
            if(a[i]>a[r])
            {
                if(c<a[r])
                z++;
                else
                c=a[r];
            }
            if(a[i]<=a[r])
            c=a[r];
        }
    }
    printf("%lld",z);
    return 0;
}

代码2(用了栈,时间超了):

#include <stdio.h>
#include<stdlib.h>
typedef struct node
{
    int sum;
    struct node*next;
}node;
typedef struct Zhan
{
    node*top;
    int g;
}zhan;
void csh(zhan *pzhan)
{
    pzhan->top=NULL;
    pzhan->g=0;
}
void push(zhan *pzhan,int sum)
{
    node*news=(node*)malloc(sizeof(node));
    news->sum=sum;
    news->next=pzhan->top;
    pzhan->top=news;
    pzhan->g++;
}
void pop(zhan *pzhan)
{
    node *poped=pzhan->top;
    pzhan->top=pzhan->top->next;
    pzhan->g--;
    free(poped);
}
int main()
{
    int i,n;
    zhan zhan;
    csh(&zhan);
    long long z=0,c=0;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%lld",&c);
        while(zhan.top!=NULL && (zhan.top->sum)<=c)
            pop(&zhan);
        z=z+zhan.g;
        push(&zhan,c);
    }
    printf("%lld\n",z);
    return 0;
}

代码3(我用了c++中的函数,最方便!!):

#include <iostream>
#include<stdio.h>
#include<algorithm>
#include<stack>
using namespace std;
stack<long long>zhan;
int main()
{
    int i,n;
    long long z=0,c=0;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%lld",&c);
        while(!zhan.empty() && (zhan.top())<=c)
            zhan.pop();
        z=z+zhan.size();
        zhan.push(c);
    }
    printf("%lld\n",z);
    return 0;
}

思路:从前往后栈,按顺序进入一个身高值,将栈中 小于(或等于)该身高的数据弹出,栈中剩下的元素对应的牛都能看见该身高的牛。算出num后入栈该身高。可以计算出,每只奶牛能被他前面的多少只奶牛看到自己的发型,就反向得到了奶牛看到的发型总和

还有一题:

羊羊们到了谈婚论嫁的年龄了,雷巨巨有的忙了。他有四种羊,每种羊分公母且公母才能配对,为方便输入用[]<>(){}代替四种羊,一天他让一些羊羊站成一排开始配对,有如下定义:假设s1和s2是满足配对的,则s2,{s1}s2,[s1]s2,(s1)s2也是满足配对的,如"[[(){}]<>]"和"{[(<>)]}"是满足配对的,而"<)()"和"]><["是不满足的,雷巨巨可以选择让其中一种羊变成另一种羊但无法改变其性别,如'<'可以变成'(','{','['但不可变成')','}',']'。问至少改变几次才能让羊羊们都找到幸福。

Input

输入一行字符串,仅由四种括号组成,长度不超过1e6

Output

如果不能使所有羊羊配对,则打印"Impossible",否则,打印最少替换的次数

Examples

Input

[<}){}

Output

2

Input

{()}[]

Output

0

Input

]]

Output

Impossible

这题我直接暴力了:

#include<stdio.h>
#include<string.h>
#define N 1000000
int main()
{
    char a[N],b[N];
    gets(a);
    int n,i,r=0,z=0,t;
    n=strlen(a);
    for(i=0;i<n;i++)
    {
        if(a[i]=='['||a[i]=='{'||a[i]=='('||a[i]=='<')
        {
          b[r]=a[i];
          r++;
        }
        if(a[i]==']'||a[i]=='}'||a[i]==')'||a[i]=='>')
        {
            switch(b[r-1])
            {
                case '(':if(a[i]!=')')z++;break;
                case '{':if(a[i]!='}')z++;break;
                case '<':if(a[i]!='>')z++;break;
                case '[':if(a[i]!=']')z++;break;
            }
            r--;
            if(r<0)
                break;
        }
    }
    if(r!=0)
        printf("Impossible");
    else
        printf("%d",z);
    return 0;
}

今天任务算是达到了,找机会总结一下动态规划和双指针,把我的推箱子美好一下。

先睡了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值