Daily
[7:40 ~ 9:50
10:00 ~ 12:10]
上午训练
12:10 ~ 1:00 恰午饭
[2:10 ~ 4:20
4:30 ~ 5:20]
下午训练
5:25 ~ 6:00 体育锻炼
6:00 ~ 6:30 恰晚饭
6:30 ~ 7:30 晚读 | | 机房补题
7:40 ~ 9:40 竞赛 && 自习
今天的训练只想写前三道关于STL(stack,queue,set)的题耶、、、
A.性格公交车(bus)
题目描述:
在一个公交车上,有n排座位,每排座位有2个座位,有2n个车站,每个车站上来一个乘客,0表示性格内向乘客,1表示性格外向乘客,你的任务是给他们排座位。排座位的要求是:
内向的人总是选择两个座位都是空的一排。在这些空座位排当中,选择一排座位宽度最小的,并占了其中的一个座位;外向的人总是选择一个内向的人所占的那排座位。在这些座位排当中,选择一排座位宽度最大的,并在其中占据了空位。现在已知n排座位的宽度和2n个乘客是内向还是外向的,以及乘客上车的顺序,你的任务是输出每一位乘客应该坐哪一排?
输入格式:
输入包含三行。第一行包含一个整数n,表示公交车上一共有n排座位。
第二行包含用n个用空格分开的整数,从左往右依次表示l_1,l_2,……,l_n的值,分别表示第1排座位的长度,第2排座位的长度,……,第n排座位的长度。
第三行包含一个包含2n个0或1字符的字符串,其中0表示性格内向乘客,1表示性格外向乘客,而且字符的顺序就是每个乘客上车的顺序。输入数据保证外向乘客的数量等于内向乘客的数量(即两个数量都等于n),并且对于每个外向乘客总是有一个合适的排。
输出格式:
输出只有一行,包含2n个正整数,分别表示乘客将坐的排号。输出乘客的顺序应与输入的顺序相同。
样例输入1:
2
3 1
0011
样例输出1:
2 1 1 2
样例输入2:
6
10 8 9 11 13 5
010010011101
样例输出2:
6 6 2 3 3 1 4 4 1 2 5 5
数据范围:
2≤n≤10^5
1≤l_i≤10^9
所有输入的数字均为整数
idea :
根据题目所说的分座位策略进行模拟,个人认为shui题一枚
0:坐一排都无人的,且越窄越好
1:就喜欢和0这种坐一堆,且越宽越好
后来听g老师说用到了栈,队列的数据结构,不由得一惊Σ(っ °Д °;)っ(难怪我A这道题时爆了)
code :
sorry,这么简单不好意思放。
B.表达式求值
题目描述:
给定一个只包含加法和乘法的算术表达式,请编程计算表达式的值。
输入格式:
输入仅有一行,为需要计算的表达式。表达式中只包含数字、加法运算符“+”和乘法运算符“*”,且没有括号,所有参与运算的数字均为 0~2^31 -1 之间的整数。输入数据保证这一行只有0~9、+、* 这 12 种字符。
输出格式:
输出只有一行,包含一个整数,表示这个表达式的值。注意:当答案长度多于 4 位时,请只输出最后 4 位,前导 0 不输出。
样例输入1:
1+1*3+4
样例输出1:
8
样例输入2:
1+1234567890*1
样例输出2:
7891
样例输入3:
1+1000000003*1
样例输出3:
4
数据范围:
对于 30% 的数据,0≤表达式中加法运算符和乘法运算符的总数≤100。
对于 80% 的数据,0≤表达式中加法运算符和乘法运算符的总数≤1000。
对于 100% 的数据,0≤表达式中加法运算符和乘法运算符的总数≤100000。
idea :
符号就很简单,但数要通过“数的拆解”的逆向思维,把两个符号之间的字符拼成数(不然输入会成一大问题)
然后按照顺序,将数push到栈里面,如果遇到 ‘*’ 号,就将两数相乘。
最后再累加起来输出好了👌
code:
#include <bits/stdc++.h>
#define maxn 2000000
#define int long long
#define sf scanf
#define pf printf
#define mod 10000
using namespace std;
char s[maxn], p[maxn];
int n, x, cnt, a[maxn], len, ans;
signed main () {
sf ("%s", s + 1);
n = strlen (s + 1);
int k = 1;
while (k <= n) {
int c = 0;
while (s[k] >= '0' && s[k] <= '9') {
c = c * 10 + s[k] - '0';
k ++;
}
p[++len] = s[k];
k ++;
a[++cnt] = c;
}
for (int i = 1; i <= len; i ++) {
if (p[i] == '*') {
a[i + 1] = (a[i] * a[i + 1]) % mod;
a[i] = 0;
}
}
for (int i = 1; i <= cnt; i ++) {
ans = (ans + a[i]) % mod;
}
pf ("%lld", ans % mod);
}
题海战(battle.cpp)
题目描述:
某信息学奥赛教练 gm 经验丰富,他的内部题库有 m 道题。他有 n 个学生,第 i 个学生已经做过p[i]道题。由于马上要进行noip考试,该教练准备举行 k 场比赛和训练。每场比赛或训练都会有一些他的学生参加,但是如何选题令他非常烦恼。对于每场比赛,他要保证所出的题没有任何一道已有任何一个学生做过;而对于每场训练,他要保证所出的所有题都被每一个参赛学生做过。
输入格式:
第1行2个正整数n和m,表示学生数和题库中的题目总量。第2~n+1行,先是1个正整数p,然后p个整数表示第i个学生的做题记录(可以重复做同一道题)。第n+2行,1个正整数k,表示要举行比赛和训练的总场数(可能有学生重复报名)。接下来的k行,每行的第1个整数type表示是训练或者比赛(1为训练,非1为比赛)。第二个数q表示参赛学生数,然后q个正整数表示参赛学生编号。每一行的两个数之间有一个空格。
输出格式:
共k行,每行表示本次训练或比赛可选的最多题目(由小到大排序,中间用一个空格隔开,如果没有输出一个空行)。
样例输入:
5 10
2 3 7
1 3
2 4 7
3 3 6 10
7 1 2 3 4 7 8 9
6
0 3 3 4 5
0 3 1 3 4
1 2 1 3
0 1 5
1 1 2
1 2 3 5
样例输出:
5
1 2 5 8 9
7
5 6 10
3
4 7
数据范围:
1 ≤ n,k ≤ 100
1 ≤ m ≤ 10000
idea :
题目肯定要去重,第一个就想到set。
1. type = 1,存没有做的题,标记不能做的题,输出能做的题(stu[z].find(*it) == stu[z].end ())
2. type = 2,同上(stu[z].find(*it) != stu[z].end ())
#include <bits/stdc++.h>
#define sf scanf
#define pf printf
#define MAXN 105
using namespace std;
set <int> stu[MAXN], quanji;
int main () {
int n, m, k;
sf ("%d %d", &n, &m);
int num, z;
for (int i = 1; i <= n; i ++) {
stu[i].clear ();
sf ("%d", &num);
for (int j = 0; j < num; j ++) {
sf ("%d", &z);
stu[i].insert (z);
}
}
for (int i = 1; i <= m; i ++) {
quanji.insert (i);
}
cin >> k;
int tybe, q;
for (int i = 0; i < k; i ++) {
set<int> ans = quanji;
cin >> tybe >> q;
if (tybe == 1) {
for (int j = 0; j < q; j ++) {
cin >> z;
for (set<int>::iterator it = ans.begin (); it != ans.end ();) {
if (stu[z].find(*it) == stu[z].end ()) {
ans.erase (it ++);
} else it ++;
}
}
for (set<int>::iterator it = ans.begin (); it != ans.end (); it ++) {
cout << *it << " ";
}
cout << endl;
} else {
for (int j = 0; j < q; j ++) {
cin >> z;
for (set<int>::iterator it = ans.begin (); it != ans.end ();) {
if (stu[z].find(*it) != stu[z].end ()) {
ans.erase (it ++);
} else it ++;
}
}
for (set<int>::iterator it = ans.begin (); it != ans.end (); it ++) {
cout << *it << " ";
}
cout << endl;
}
}
}