目录
A. 表达式求值
说明
给定一个只包含加法和乘法的算术表达式,请你编程计算表达式的值。
输入格式
每组输入数据仅有一行,为需要你计算的表达式,表达式中只包含数字、加法运算符“+”和乘法运算符“*”,且没有括号,所有参与运算的数字均为0到231-1之间的整数。输入数据保证这一行只有0~9、+、*这12种字符。
数据规模:
对于30%的数据,0≤表达式中加法运算符和乘法运算符的总数≤100;
对于80%的数据,0≤表达式中加法运算符和乘法运算符的总数≤1000;
对于100%的数据,0≤表达式中加法运算符和乘法运算符的总数≤100000。
输出格式
每组输出只有一行,包含一个整数,表示这个表达式的值。注意:当答案长度多于4位时,请只输出最后4位,前导0不输出。
下面是对样例数据的解释:
样例1计算的结果为8,直接输出8。
样例2计算的结果为1234567891,输出后4位,即7891。
样例3计算的结果为1000000004,输出后4位,即4。
样例
输入数据 1
1+1*3+4 1+1234567890*1 1+1000000003*1
Copy
输出数据 1
8 7891 4
由于是一个只包含加法和乘法的算术表达式,所以我们可以先将乘法全部处理之后再处理加法
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int mod = 10000;
int f;
int ls;
int sum;
int main() {
string s;
while (cin >> s) {
stack<char>st;//保存‘+’号
stack<int>st2;//保存数字
int q = 0;
int ppx = s.size();
for (int i = 0; i < ppx; i++) {
if (s[i] >= '0' && s[i] <= '9') {//算出数字的结果
q = (q * 10 + (s[i] - '0')) % mod;
}
if (i == ppx - 1||s[i]=='+'||s[i]=='*') {//如果不是数字
if (f) {//如果这个数字前面是‘*’号,算出乘后的结果入栈
q = q * ls % mod;
st2.push(q);
f = 0;
}
else st2.push(q);//直接进栈
q = 0;
if (s[i] == '+') {//如果是‘+’号,直接入栈
st.push(s[i]);
}
else if (s[i] == '*') {//如果是‘*’号,用ls记录‘*’号前的数字
ls = st2.top();
st2.pop();
f = 1;
}
}
}
while (st.size()) {//对‘+’法进行处理
st.pop();
int l = st2.top();
st2.pop();
int r = st2.top();
st2.pop();
st2.push((l + r) % mod);
}
cout << st2.top() << endl;//输出结果
}
return 0;
}
B. 栈
说明
栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表。
栈有两种最重要的操作,即pop(从栈顶弹出一个元素)和push(将一个元素进栈)。
栈的重要性不言自明,任何一门数据结构的课程都会介绍栈。宁宁同学在复习栈的基本概念时,想到了一个书上没有讲过的问题,而他自己无法给出答案,所以需要你的帮忙。
宁宁考虑的是这样一个问题:一个操作数序列,从1,2,一直到n(图示为1到3的情况),栈A的深度大于n。
现在可以进行两种操作:
1. 将一个数,从操作数序列的头端移到栈的头端(对应数据结构栈的push操作)
2. 将一个数,从栈的头端移到输出序列的尾端(对应数据结构栈的pop操作)使用这两种操作,由一个操作数序列就可以得到一系列的输出序列,下图所示为由1 2 3生成序列2 3 1的过程。(原始状态如上图所示)
你的程序将对给定的n,计算并输出由操作数序列1,2,...,n经过操作可能得到的输出序列的总数。
输入格式
输入只含一个整数n(1≤n≤18)。
输出格式
输出只有一行,即可能输出序列的总数目。
样例
输入数据 1
3
Copy
输出数据 1
5
遇事不绝就百度,可知此题的结果是卡特兰数的规律:
设h(n)为catalan数的第n项,令h(0)=1,h(1)=1,catalan数满足递推式:h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)*h(0) (n≥2)
所以直接写代码即可
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n;
int ca[20];
//设h(n)为catalan数的第n项,令h(0)=1,h(1)=1,catalan数满足递推式
//h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)*h(0) (n≥2)
ll Catalan(int n) {
if (ca[n]) {
return ca[n];
}
if (n == 0||n==1) {
ca[n] = 1;
return 1;
}
for (int i = 0; i <= n - 1; i++) {
ca[n] += Catalan(i) * Catalan(n - i - 1);
}
return ca[n];
}
int main() {
cin >> n;
cout << Catalan(n);//卡特兰数
return 0;
}
C. 「一本通 5.1 练习 1」括号配对
题目描述
Hecy 又接了个新任务:BE 处理。BE 中有一类被称为 GBE。
以下是 GBE 的定义:
- 空表达式是 GBE
- 如果表达式
A
是 GBE,则[A]
与(A)
都是 GBE- 如果
A
与B
都是 GBE,那么AB
是 GBE下面给出一个 BE,求至少添加多少字符能使这个 BE 成为 GBE。
输入格式
输入仅一行,为字符串 BE。
输出格式
输出仅一个整数,表示增加的最少字符数。
样例
输入数据 1
[])
Copy
输出数据 1
1
Copy
数据范围与提示
对于 100%100% 的数据,输入的字符串长度小于 100100。
区间dp,从1~n逐步推出最佳结果,重点是理清思路趴,大家多看几遍
#include <bits/stdc++.h>
using namespace std;
int f[105][105];//f[i][j]是区间i到j的最少操作数
int main() {
string s;
cin >> s;
int n = s.size();
for (int i = 0; i < n; i++)f[i][i] = 1;
//当区间长度为0时,每个字符找到匹配的操作数为1
for (int L = 1; L < n; L++) { //枚举区间长度
for (int i = 0; i + L < n; i++) { //遍历区间起点
int j = i + L;//区间终点
f[i][j] = 1e9;//首先赋一个最大的值
for (int k = i; k < j; k++) //遍历区间
f[i][j] = min(f[i][j], f[i][k] + f[k + 1][j]);
if ((s[i] == '[' && s[j] == ']') || (s[i] == '(' && s[j] == ')')) //如果括号匹配
f[i][j] = min(f[i][j], f[i + 1][j - 1]);
}
}
/*for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cout << f[i][j] << ' ';
}
cout << endl;
}*/
cout << f[0][n - 1] << endl;
return 0;
}
D. 奶牛舞会
Description
每年春天,奶牛们会举行一个盛大的舞会。
舞会上公牛(表示为">")和母牛(表示为"<")相互鞠躬以后开始舞蹈。
原则上,一对相互鞠躬的牛表示为:"><"。直接这样"<>"都不行;
有时候,另一对牛会处在一对相互鞠躬的牛中间:"> >< <"。
事实上,有些时候舞厅会有非常多的牛会混杂在一起:"> >< < ><"。
会比上面的例子更复杂一点(右侧又多加了一对相互鞠躬的牛)。
如下是一个更复杂但合法的安排: > > > >< < >< < >< >< >< <
Farmer John注意到有时会有游荡的牛闯入一组跳舞者中,因此这个跳舞组变得不平衡:"> >< < <><"。 这是严格禁止的。
Farmer John想要惩罚这些闯入者。 Farmer John整理出一些跳舞队列的记录。每个跳舞队列最多有500只牛。
他想要知道这些跳舞队列是否平衡。
平衡也就是说至少有一种方案可以使每头牛都加入一个鞠躬对。
Format
Input
Farmer John一共整理出 ==N组记录(1 <= N <= 1,000)==。
第i组记录由字符('>' and '<')和一个表示长度的K_i (1 <= K_i <=200)构成。 .
Output
如果记录可以平衡,输出"legal",否则,输出"illegal".
Samples
输入数据1
输入数据 1
2 6 >><<>< 4 ><<>
Copy
输出数据 1
legal illegal
Copy
输出数据1
Samples
输入数据2
输入数据 2
7 5 <<<<< 5 >>>>> 2 >< 3 >>< 9 >><<><><< 11 ><><>><<>>< 4 >><<
Copy
输出数据 2
illegal illegal legal illegal illegal illegal legal
Copy
输出数据2
Limitation
1s, 1024KiB for each test case.
签到题趴,放在最后的最简单
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main() {
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
stack<char>st;
for (int i = 0; i < n; i++) {
char x;
cin >> x;
if (x == '>') {
st.push(x);
}
else {
if (st.size()&&st.top() == '>') {//如果栈不为空且栈顶元素和现有元素匹配
st.pop();
}
else st.push(x);
}
}
if (st.size())cout << "illegal\n";
else cout << "legal\n";
}
return 0;
}