7.11 ~ 7.16 训练开幕

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;
		}
	}
}

总结:

在各题中,stack(栈)显得尤为重要,要加强训练。

ヾ(•ω•`)o--==明天见

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值