大一寒假训练:栈

一、关于栈:

FILO (First In Last Out)

二、专题练习&题解:

(没错我懒了,具体介绍搜就行)

1.栈-程序员输入问题

这里要注意最好不要用单个字符在输入时就做判断(TLE,我也不知道为啥),而且cin读单个字符,敲下回车是不会读入’\n’的。

#include <bits/stdc++.h>
using namespace std;

int main()
{
    stack<char>str,str1;
    char a[101];
    gets(a); //字符串含空格
    for(int i=0;i<strlen(a);i++)
    {
        if(a[i]=='@')
            while(!str.empty())
            {str.pop();continue;}
        if(a[i]=='#')
            {str.pop();continue;}
        if(a[i]!='#'&&a[i]!='@')
            str.push(a[i]);
    }
    while(!str.empty())
    {
        str1.push(str.top());
        str.pop();
    }
    while(!str1.empty())
    {
        cout<<str1.top();
        str1.pop();
    }
    return 0;
}

2.栈-溶液模拟器

没用栈写,所以可能繁琐一点。思路就是输入P就输入加的V和C,再计算并记录加完后的V和C,遇到Z就输出上一次的记录。

#include <bits/stdc++.h>
using namespace std;

struct yeti
{
    char ch;
    int vi,vz;
    double ci,cz;
}x[10005];
int main()
{
    int v0,n;
    double c0;
    cin>>v0>>c0>>n;
    for(int i=1;i<=n;i++)
    {
        getchar();
        cin>>x[i].ch;
        if(i==1&&x[i].ch=='Z')
        {
            printf("%d %.5lf\n",v0,c0);
            i-=1;n-=1;  //因为Z没有输入,所以在该i值情况下没有输入,让i-1保持上次的记录;又因为Z也是一次
            continue;   //操作,所以n-1;
        }
        if(i!=1&&x[i].ch=='Z')
            {
                if(i-2!=0)  //为什么是-2在纸上算一下即可
                printf("%d %.5lf\n",x[i-2].vz,x[i-2].cz);
                else
                    printf("%d %.5lf\n",v0,c0);
                i-=2;n-=2;
                continue;}
        if(i==1&&x[i].ch=='P')
        {
            cin>>x[i].vi>>x[i].ci;
            x[i].vz=v0+x[i].vi;
            x[i].cz=(c0*v0*0.01+x[i].vi*x[i].ci*0.01)/(x[i].vz)*100; //此处注意*0.01再计算才有小数位变化
            printf("%d %.5lf\n",x[i].vz,x[i].cz);
        }
        if(i!=1&&x[i].ch=='P')
        {
            cin>>x[i].vi>>x[i].ci;
            x[i].vz=x[i-1].vz+x[i].vi;
            x[i].cz=(x[i-1].cz*x[i-1].vz*0.01+x[i].vi*x[i].ci*0.01)/(x[i].vz)*100;
            printf("%d %.5lf\n",x[i].vz,x[i].cz);
        }

    }
    return 0;
}

3.栈-火车编组

我真是服了这题的描述,看了好一会才懂说的是啥意思:按升序进行进出栈操作,使得操作完成后出栈排成的序列为输入的序列。例如输入3 2 4 1,则1、2、3先进栈(AAA),3、2再出栈(BB),4再进栈(A),4、1最后出栈(BB),则出栈顺序为3 2 4 1,所以AAABBABB。

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n, str[105], t;
    stack<int> temp, final;//temp进,final出
    while (cin >> n) 
    {
        int pos=1; //作为一个“指针”
        for (int i = 1; i <= n; i++)
            cin >> str[i];
        for (int i = n; i >= 1; i--)
            temp.push(i);
        while (!temp.empty())
        {
        //思路是让所有<=str[i]的车厢先进栈,然后让等于str[i]的车厢出栈
            if (temp.top() <= str[pos])
            {
                t = temp.top();
                final.push(t);
                temp.pop();
                cout << "A";
            }
            if (final.top() == str[pos])
            {
                final.pop();
                cout << "B";
                pos++;
            }
        }
        while (!final.empty()) //保证所有车厢全部出栈
        {
            cout << "B";
            final.pop();
        }
        cout << endl;
    }
    return 0;
}

4.栈-洗盘子

需注意是“输入若干行

#include <bits/stdc++.h>
using namespace std;
int str[10005][2];

int main()
{
    ios::sync_with_stdio(false);
    int n;
    stack<int> initial, wash, wipe;
    while (cin >> n)
    {
        int total = 0, pos = 0;//pos记录输入的行数
        int ans;
        for (int i = 1;; i++)
        {
            cin >> str[i][0] >> str[i][1];
            pos++;
            if (str[i][0] == 2)//当盘子擦完,停止输入
            {
                total += str[i][1];
                if (total == n)
                {
                    break;
                }
            }
        }
        for (int i = n; i >= 1; i--)
            initial.push(i);
        for (int i = 1; i <= pos; i++)
        {
            if (str[i][0] == 1)//==1时从initial进wash
            {
                while (str[i][1]--)
                {
                    wash.push(initial.top());
                    initial.pop();
                }
            }
            else//==2时从wash进wipe
            {
                while (str[i][1]--)
                {
                    wipe.push(wash.top());
                    wash.pop();
                }
            }
        }
        while (n--)//最后输出
        {
            ans = wipe.top();
            wipe.pop();
            cout << ans << endl;
        }
    }
    return 0;
}

5.栈-括号匹配

“消消乐”?从内往外消对子,有剩的就Wrong了

#include <bits/stdc++.h>
using namespace std;

int main()
{
    string str;
    cin>>str;
    stack<char> temp;
    for (int i = 0; i < str.size(); i++)
    {
        if (str[i] == '(' || str[i] == '['||temp.empty()//有一开始为')',']'的情况)
        {
            temp.push(str[i]);
            continue;
        }
        if (temp.top() == '(' && str[i] == ')')
            temp.pop();
        else if (temp.top() == '[' && str[i] == ']')
            temp.pop();
        else
            temp.push(str[i]);
    }
    if (temp.empty())
        cout << "OK" << endl;
    else
        cout << "Wrong" << endl;
    return 0;
}

6.栈-表达式求值

注意乘法的优先级

#include <bits/stdc++.h>
using namespace std;
const int mod = 1e4;

int main()
{
    int x, t, ans = 0;
    char ch;
    cin >> x;
    t = x % mod;
    while (scanf("%c", &ch) && ch != '\n') //这里不能用cin,cin读入回车不是'\n'
    {
        cin >> x;
        x = x % mod;
        if (ch == '*')
            t = t * x % mod;
        else
        {
            ans = ans + t % mod;
            t = x;
        }
    }
    ans = ans + t;
    cout << ans % mod << endl;
    return 0;
}

时隔一个月,我终于把这章补完了,竟无聊到学习。这假越过越长?

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值