c++栈的应用初步

整理了4道“栈的应用”

Q1:(入门)
问题 A: 程序员输入问题
时间限制: 1 Sec 内存限制: 128 MB
题目描述
【问题描述】
程序员输入程序出现差错时,可以采取以下的补救措施:按错了一个键时,可以补按一个退格符“#”,以表示前一个字符无效;发现当前一行有错,可以按一个退行符“@”,以表示“@”与前一个换行符之间的字符全部无效。
【输入格式】
输入一行字符,个数不超过 100。
【输出格式】
输出一行字符,表示实际有效字符。
【输入样例】
sdfosif@for(ii#=1,#;i<.#=8;i+++#);
【输出样例】
for(i=1;i<=8;i++);

直接上代码:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    char s[101];
    stack <char> a;
    stack <char> b;
    gets(s);
    for(int i=0;i<strlen(s);i++)
	{
        if(s[i]=='@')
		{
            while(!a.empty())
			{
                a.pop();
            }
            continue;
        }
        if(s[i]=='#')
		{
            if(!a.empty())
			{
                a.pop();
                continue;
            }
        }
        a.push(s[i]);
    }
    while(!a.empty())
	{
        b.push(a.top());
        a.pop();
    }
    while(!b.empty())
	{
        cout<<b.top();
        b.pop();
    }
    cout<<endl;
    return 0;
}

AC
W2:这题有点 烦人
问题 B: 溶液模拟器
时间限制: 1 Sec 内存限制: 128 MB
题目描述
小谢虽然有很多溶液,但是还是没有办法配成想要的溶液,因为万一倒错了就没有办法挽回了。因此,小谢到网上下载了一个溶液配置模拟器。模拟器在计算机中构造一种虚拟溶液,然后可以虚拟地向当前虚拟溶液中加入一定浓度、一定体积的这种溶液,模拟器会快速地算出倒入后虚拟溶液的浓度和体积。当然,如果倒错了可以撤销。
模拟器的使用步骤如下:
1)为模拟器设置一个初始体积和浓度 V0、C0%。
2)进行一系列操作,模拟器支持两种操作:
P(v,c)操作:表示向当前的虚拟溶液中加入体积为 v 浓度为 c 的溶液;
Z 操作:撤销上一步的 P 操作。
输入
第一行两个整数,表示 V0 和 C0,0≤C0≤100;
第二行一个整数 n,表示操作数,n≤10000;
接下来 n 行,每行一条操作,格式为:P_v_c 或 Z。
其中 _ 代表一个空格,当只剩初始溶液的时候,再撤销就没有用了。
任意时刻质量不会超过 2^31 -1。
输出
n 行,每行两个数 Vi,Ci,其中 Vi 为整数,Ci 为实数(保留 5 位小数)。
其中,第 i 行表示第 i 次操作以后的溶液体积和浓度。
样例输入 Copy
100 100
2
P 100 0
Z

稍微想想就好了:

#include <bits/stdc++.h>
using namespace std;
struct ry
{
    int v;
    double c;
};
stack<ry>vis;
int main()
{
    ios::sync_with_stdio(0);
    char p;
    int v0,v1,v2,n;
    double c0,c1,c2;
    cin>>v0>>c0>>n;
    v2=v0;
    c2=c0;
    for(int i=0;i<n;i++)
	{
        cin>>p;
        if(p=='P')
		{
            cin>>v1>>c1;
            vis.push({v1,c1});
            c0=(v0*c0+v1*c1)/(v0+v1);
            c0=c0;
            v0=v0+v1;
            printf("%d %.5lf\n",v0,c0);
        }
        else
		{
            if(vis.empty())
			{
                printf("%d %.5lf\n",v2,c2);
                continue;
            }
            ry tmp=vis.top();
            vis.pop();
            v1=tmp.v;
            c1=tmp.c;
            c0=(v0*c0-v1*c1)/(v0-v1);
            v0=v0-v1;
            printf("%d %.5lf\n",v0,c0);
        }
    }
    return 0;
}

这题也是一次性通过;
W3:
问题 C: 表达式括号匹配
时间限制: 1 Sec 内存限制: 128 MB
题目描述
假设一个表达式有英文字母(小写)和数字、运算符(+,—,,/)和左右小(圆)括号构成,以“@”作为表达式的结束符。请编写一个程序检查表达式中的左右圆括号是否匹配,若匹配,则返回“YES”;否则返回“NO”。表达式长度小于255,左圆括号少于20个。
输入
输入文件包括一行数据,即表达式,
输出
输出文件包括一行,即“YES” 或“NO”。
样例输入 Copy
2
(x+y)/(1-x)@
样例输出 Copy
YES

本人这题交了5遍才AC,前4次都是内存超限:
错误:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    char s[300];
    stack <char> a;
    scanf("%s",s);
    for(int i=0;i<strlen(s);i++)
	{
        if(a.empty()) a.push(s[i]);
        else
		{
            if(a.top()=='['&&s[i]==']'||a.top()=='('&&s[i]==')')
                a.pop();
            else
                a.push(s[i]);
        }
    }
    if(a.empty()) cout<<"YES"<<endl;
    else cout<<"NO"<<endl;
    return 0;
}

内存超限

AC正确版本:

#include<bits/stdc++.h>
using namespace std;
#define N 260
int main()
{
char s[N];
int top=0,i=0;
scanf("%s",s);
while(s[i]!='@')
{
    if(s[i]=='(')
           top++;
    if(s[i]==')')
    {
        if(top>0) top--;
        else
        {
            cout<<"NO"<<endl;
            return 0;
        }
    }
    i++;
}

if(top!=0)  
cout<<"NO"<<endl;
else 
cout<<"YES"<<endl;
  return 0;
}

大家去试试吧!
Q4:
问题 D: 表达式求值
时间限制: 1 Sec 内存限制: 512 MB
提交: 43 解决: 16
[状态] [提交] [命题人:外部导入]
题目描述
给定一个只包含加法和乘法的算术表达式,请你编程计算表达式的值。
输入
输入仅有一行,为需要你计算的表达式,表达式中只包含数字、加法运算符“+”和乘法运算符“*”,且没有括号,所有参与运算的数字均为0到2^31-1之间的整数。输入数据保证这一行只有0~9、+、*这12种字符。

【数据范围】
对于30%的数据,0≤表达式中加法运算符和乘法运算符的总数≤100;
对于80%的数据,0≤表达式中加法运算符和乘法运算符的总数≤1000;
对于100%的数据,0≤表达式中加法运算符和乘法运算符的总数≤100000。

输出
输出只有一行,包含一个整数,表示这个表达式的值。注意:当答案长度多于4位时,请只输出最后4位,前导0不输出。
样例输入 Copy
1+1*3+4
样例输出 Copy
8

大家先去思考思考如何去解题,然后再copy。
这是AC版本:

#include <bits/stdc++.h>

using namespace std;

int main()
{
    stack <int>a;
    int t,s=0;
    char ch='+';
    while(ch=='+'||ch=='*')
    {
        cin >> t ;
        t=t%10000;
        if(ch=='+')
            a.push(t);
        else if(ch=='*')
        {
            t=(a.top()*t)%10000;
            a.pop();
            a.push(t);
        }
        ch=getchar();
    }
    while(!a.empty())
    {
        s=(s+a.top())%10000;
        a.pop();
    }
    cout<<s<<endl;
    return 0;
}


现在请各位大神看下如下有何错误,谢谢!

#include <bits/stdc++.h>
using namespace std;
const int mod=1e4;
char c;
int x,sum,ans;
int main()
{
    scanf("%d",&x);sum=x%mod;
    while(scanf("%c",&c)&&c!='\n')
    {
        scanf("%d",&x);
        x=x%mod;
        if(c=='*')
            sum=sum*x%mod;
        else 
		{
            ans=ans+sum%mod;
            sum=x%mod;
        }
    }
    ans=ans+sum%mod;
    printf("%d\n",sum%mod);
    return 0;
}

好啦,就这么多啦,快去练练手吧!

猜你喜欢

转载自blog.csdn.net/AdamNZhang/article/details/107425786