栈
用栈来计入表达式的值
遇乘号(说明两数相乘中乘号前的那个数已经被放入栈中,成为栈顶元素了)就将数乘栈顶元素再放进栈中(以前的栈顶元素要取出来然后再放进乘完后的元素),加号就直接放,因此栈中的数最后都是相加起来,
#include <iostream>
#include <stack>
using namespace std;
stack <int> x;//一个存数字并在最后把它们相加的栈
int main()
{
int a,b;
char c;
pintf("%d",&a);//先输入一个数,以后符号+数字输入
int m=10000;
a=a%m;//必须的操作
x.push(a);//压入栈中
while(while("%c %d",&c,&b)!=EOF)
{
if(c=='*')//将*之前的数字与*之后的数字积存入
{
a=x.top();//此时top顶的数就是相乘数中的一个数
x.pop();
x.push(a*b%m);//取两数之积的摸;
}
else//将b存入
x.push(b);
}
a=0;
while(x.size())//将所有数都加起来
{
a+=x.top();
a%=m;//取模
x.pop();
}
printf("%d",a);
return 0;
}
括号匹配是使用栈解决的经典问题
建议要写代码之前要分析好有哪几种不匹配的情况,如果不动手之前分析好,写出的代码也会有很多问题。
先来分析一下 这里有三种不匹配的情况,
- 第一种情况,字符串里左方向的括号多余了,所以不匹配。
- 第二种情况,括号没有多余,但是括号的类型没有匹配上。
- 第三种情况,字符串里右方向的括号多余了,所以不匹配。
这里还有一些技巧,在匹配左括号的时候,右括号先入栈,就只需要比较当前元素和栈顶相不相等就可以了,比左括号先入栈代码实现要简单的多了!
#include<stdio.h>
#include<string.h>
int main()
{
char a[300];int cnt1=0,cnt2=0;
scanf("%s",a);
a[strcspn(a, "\n")] = 0;
int t=strlen(a);int i;
for( i=0;i<t;i++){
if(a[i]==')') cnt1++;
if(cnt1>cnt2){
printf("NO");//在整个式子中,左括号的数量累加的速度一定比右括号慢
return 0;
}
if(a[i]=='(')cnt2++;
}
if(cnt1==cnt2){
printf("YES");
}
else{
printf("NO");
}
}
双向队列
一、概述
deque(双端队列)是由一段一段的定量连续空间构成,可以向两端发展,因此不论在尾部或头部安插元素都十分迅速。 在中间部分安插元素则比较费时,因为必须移动其它元素。
二、定义及初始化
#include <deque> // deque属于std命名域的,因此需要通过命名限定,
deque<int> a; // 定义一个int类型的双端队列a
deque<int> a(10); // 定义一个int类型的双端队列a,并设置初始大小为10
deque<int> a(10, 1); // 定义一个int类型的双端队列a,并设置初始大小为10且初始值都为1
deque<int> b(a); // 定义并用双端队列a初始化双端队列b
deque<int> b(a.begin(), a.begin()+3); // 将双端队列a中从第0个到第2个(共3个)作为双端队列b的初始值
三、基本操作函数
3.1 容量函数
- 容器大小:
deq.size();
- 容器最大容量:
deq.max_size();
- 更改容器大小:
deq.resize();
- 容器判空:
deq.empty();
- 减少容器大小到满足元素所占存储空间的大小:
deq.shrink_to_fit();
3.3 删除函数
- 头部删除元素:
deq.pop_front();
- 末尾删除元素:
deq.pop_back();
- 任意位置删除一个元素:
deq.erase(iterator it);
- 清空所有元素:
deq.clear();
#include<bits/stdc++.h>
using namespace std;
deque<long long> g;//双向队列
long long k,x,j,n,op,m,i,t,w,y,a[3000005];
int main()
{
scanf("%lld %lld %lld",&n,&m,&k);//人数 次数 范围
for(i=1;i<=n;i++)scanf("%lld",&a[i]);//输入
sort(a+1, a+1+n);
for(i=1;i<=n;i++)g.push_back(a[i]);//入队 先入小的(小的数在头部)
while(m--){
scanf("%lld",&op);
if(op==1){
scanf("%lld",&x);//正移x
y+=x;
while(!g.empty()){
w=g.back();//取得是尾部的大数
if(w+y>k) g.pop_back();//如果此埴轮移动完超过k,就被淘汰了 (出队
else break;//执行这个代表该出队的都出了
}
}
else if(op==2){
scanf("%lld",&x);//负移x
y-=x;
while(!g.empty()) {
w = g.front();//头部是小一点的数
if(w+y<-k)g.pop_front();//如果此埴轮移动完小于-k,也会被淘汰 (从队头弹出)
else break;
}
}
else if(op==3){
printf("%lld\n",g.size());
}
}
}