2022年天梯赛

L1-1 今天我要赢

门钥匙

题意:

输出两行:第一行固定字符串“I’m gonna win! Today!”,第二行根据“比赛前一天2022-04-23”推出当天日期,并按“年年年年-月月-日日”格式输出。

解答:

签到题

1
2
3
4
void solve(){
cout << "I'm gonna win! Today!" << '\n';
cout << "2022-04-23" << '\n';
}

L1-2 种钻石

门钥匙

题意:

输入需求量N(≤10⁷微克拉)和培育速度v(1≤v≤200微克拉/天)。计算培育N微克拉钻石所需整数天数(向下取整)。

解答:

签到题

1
2
3
4
5
void solve(){
int n,v;
cin >> n >> v;
cout << n/v << '\n';
}

L1-3 谁能进图书馆

门钥匙

题意:

图书馆规定:

  1. 年龄小于“禁入年龄线”的儿童不能自己进。

  2. 年龄大于等于“陪同年龄线”的成人可以陪同儿童进。

  3. 题目给两个询问者的年龄,判断他们能不能进,并按照特定规则输出对话。

输入:

输入在一行中给出 4 个整数:

禁入年龄线 陪同年龄线 询问者1的年龄 询问者2的年龄

禁入年龄线是指严格小于该年龄的儿童禁止入馆,陪同年龄线是指大于等于该年龄的人士可以陪同儿童入馆

默认两个询问者的编号依次分别为 12;年龄和年龄线都是 [1, 200] 区间内的整数,并且保证 陪同年龄线 严格大于 禁入年龄线

输出:

在一行中输出对两位询问者的回答,如果可以进就输出 年龄-Y,否则输出 年龄-N,中间空 1 格,行首尾不得有多余空格

在第二行根据两个询问者的情况输出一句话:

  • 如果两个人必须一起进,则输出 qing X zhao gu hao Y,其中 X 是陪同人的编号, Y 是小孩子的编号;
  • 如果两个人都可以进但不是必须一起的,则输出 huan ying ru guan
  • 如果两个人都进不去,则输出 zhang da zai lai ba
  • 如果一个人能进一个不能,则输出 X: huan ying ru guan,其中 X 是可以入馆的那个人的编号。

解答:

这道题条件很多,要不断地分类讨论。这道题 大概 有四种输出情况:

  1. 两个人必须一起进

  2. 两个人都可以各自进去

  3. 两个人都不能进

  4. 一个人能进,一个人不能进

当然,要判断这四个关系,我们还需要去讨论根本的东西:每个人是否能单独入馆以及陪同关系

所以我们很轻松 骗你的,并不轻松,写的时候生怕WA了 就能得到 屎山 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void solve(){
int bana,coma,a1,a2;
cin >> bana >> coma >> a1 >> a2;
//判断能否单独入馆
bool x1 = (a1 >= bana);
bool x2 = (a2 >= bana);
//判断是否能陪同或被陪同
bool y1 = (a1 >= coma);
bool y2 = (a2 >= coma);
//判断最终是否能入馆
bool z1 = x1 || y2;
bool z2 = x2 || y1;

cout << a1 << (z1 ? "-Y" : "-N") << " ";
cout << a2 << (z2 ? "-Y" : "-N") << '\n';

if(z1 && z2) //两人都能进
if(!x1 || !x2){ //要陪同
if(!x1) cout << "qing 2 zhao gu hao 1" << '\n';
else cout << "qing 1 zhao gu hao 2" << '\n';
}else{ //都能单独进
cout << "huan ying ru guan" << '\n';
}
else if(!z1 && !z2) //两人都不能进
cout << "zhang da zai lai ba" << '\n';
else
if(z1) cout << "1: huan ying ru guan" << '\n';
else cout << "2: huan ying ru guan" << '\n';
}

L1-4 拯救外星人

门钥匙

题意:

给出两个正整数 A 和 B,输出 (A+B) 的阶乘,题目保证 (A+B) 的值小于 12

解答:

签到题

1
2
3
4
5
6
7
8
9
10
11
12
using ll = long long;
//当然有些人喜欢typedef long long ll;

void solve(){
int a,b;
cin >> a >> b;
a += b;
ll res = 1;
for(int i = 1;i <= a;++i)
res *= i;
cout << res << '\n';
}

L1-5 试试手气

门钥匙

题意:

有 6 个骰子,每个骰子初始时有一个朝上的点数。每次摇骰子,每个骰子都要换一个点数,并且不能和它之前任何一次摇出的点数重复(包括初始状态)。每次都要让每个骰子得到当前可能的最大点数。问你第 n 次摇完后,6 个骰子的点数分别是多少。

输入:

输入第一行给出 6 个骰子的初始点数,即 [1,6] 之间的整数,数字间以空格分隔;第二行给出摇的次数 n(1≤n≤5)

输入第一行给出 6 个骰子的初始点数,即 [1,6] 之间的整数,数字间以空格分隔;第二行给出摇的次数 n(1≤n≤5)

输出:

在一行中顺序列出第 n 次摇出的每个骰子的点数。数字间必须以 1 个空格分隔,行首位不得有多余空格

样例:

3 6 5 4 1 4(in)

3

4 3 3 3 4 3 (out)

6 5 6 6 6 6 (解释)

解答:

法一:可以创建一个vis数组来记录每个筛子出现的值,初始化为0,记下标为出现的值的元素(数组项)为1。对于每个筛子,从6 -> 1依次遍历…… 当然,这样略显麻烦。

法二:可以用set来记录出现过的点数,因为set不允许存储重复元素,非常适合记录每个筛子已经出现的点数,同时,set的count()和find()操作还是非常快的(O(log n))。

在遍历的过程中,如果当前点数没有使用过,那就记下当前的点数,并且将该点数insert到set中,反之,去考虑下一个骰子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void solve(){
set<int> vis[7]; //不要错写成(),这里是申请了7个
for(int i = 1;i <= 6;++i){
int x; cin >> x;
vis[i].insert(x); //这里千万不要错写成vis.insert(x)
}
int n;
cin >> n;

vector<int> res(7);
for(int i = 1;i <= n;++i) //摇骰子的次数
for(int j = 1;j <= 6;++j) //遍历6个骰子
for(int k = 6;k >= 1;--k){ //从大到小
if(!vis[j].count(k)){
res[j] = k;
vis[j].insert(k);
break;
}
}
for(int i = 1;i <= 6;++i){
cout << res[i];
if(i < 6) cout << ' ';
}
cout << '\n';
}

L1-6 斯德哥尔摩火车上的题

门钥匙

题意:

题目给了你一段代码,然后让你判断输入的两个仅由数字组成的非空字符串经过该代码处理后得出的结果是否一样。一样就输出结果,否则就输出各自对应的处理结果。

解答:

直接把代码cv过去就行了 合理利用题目已知条件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void solve(){
string a,b,s1,s2;
cin >> a >> b;

for(int i = 1;i < a.length();++i)
if((a[i]%2 == a[i-1]%2))
s1 += max(a[i],a[i-1]);

for(int i = 1;i < b.length();++i)
if((b[i]%2 == b[i-1]%2))
s2 += max(b[i],b[i-1]);

if(s1 == s2) cout << s1 << '\n';
else{
cout << s1 << '\n';
cout << s2 << '\n';
}
}

L1-7 机工士姆斯塔迪奥

门钥匙

题意:

有一个N 行 M 列的网格(1×1 格子)。

BOSS会释放Q次技能,每次可能是“一整行”或“一整列”被标记为不安全。

输入的 Ti, Ci:

Ti = 0:选中的是行,行号是Ci。

Ti = 1:选中的是列,列号是Ci。

一个格子如果它所在的行或所在的列被标记了,就不安全。

最后要输出安全的格子数。

解答:

因为数据量不是很大,所以可以创建一个数组,初始化为0,记被标记的点为1,最后统计1的个数,再让总格子数减去1的个数(或者统计0的个数,直接输出)。

对于创建数组的方式,你可以选择创建二维数组,也可以选择一维数组(虽然比较麻烦)。下面贴出青涩的 很麻烦的 一维数组的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const int N = 1e5+10;
int g[N];

void solve(){
int n,m,q;
cin >> n >> m >> q;
int res = 0;
while(q--){
int t,c;
cin >> t >> c;
if(t == 0)
for(int i = (c-1)*m;i < c*m;++i) g[i] = 1;
else if(t == 1)
for(int i = c-1;i < n*m;i += m) g[i] = 1;
}
for(int i = 0;i < n*m;++i)
if(g[i] == 0) res++;

cout << res << '\n';
}

L1-8 静静的推荐

门钥匙

题意:

企业接受推荐流程:

  • 学生只有天梯赛分数 ≥ 175才考虑。

  • 一共 K 批推荐名单,同一批内成绩严格递增。

  • 若两个学生的天梯赛分数相同,其中一个 PAT ≥ S(S 是面试分数线),那么这个学生仍然可以跟同分数的另一人进入同一批

要求我们最大化推荐人数。

解答:

可以先创建一个cnt数组,计入每个分数的总人数,再记录ok数组,用来记录各个分数中pat分数≥s的人数。对于每个分数,可以先取pat没过线的,即min(cnt[i] - ok[i],k)人,再把ok[i]全部加起来。代码参考如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void solve(){
int n,k,s;
cin >> n >> k >> s;
vector<int> cnt(291),ok(291);
for(int i = 0;i < n;++i){
int score,pat;
cin >> score >> pat;
if(score >= 175){
cnt[score]++;
if(pat >= s) ok[score]++;
}
}
int res = 0;
for(int i = 175;i <= 290;++i)
res += min(cnt[i]-ok[i],k)+ok[i];

cout << res << '\n';
}

L2-1 查松枝

L2-2 老板的作息表

L2-3 龙龙送外卖

L2-4 大众情人

L3-1 千手观音

L3-2 关于深度优先搜索和逆序对的题应该不会很难吧这件事

L3-3 教科书般的亵渎