文章目录
L1-1 今天我要赢
2018 年我们曾经出过一题,是输出“2018 我们要赢”。今年是 2022 年,你要输出的句子变成了“我要赢!就在今天!”然后以比赛当天的日期落款。
输入格式:
本题没有输入。
输出格式:
输出分 2 行。在第一行中输出 I’m gonna win! Today!,在第二行中用 年年年年-月月-日日 的格式输出比赛当天的日期。已知比赛的前一天是 2022-04-22。
输入样例:
无
输出样例(第二行的内容要你自己想一想,这里不给出):
I'm gonna win! Today!
这一行的内容我不告诉你…… 你要自己输出正确的日期呀~
#include <bits/stdc++.h>
using namespace std;
int main()
{
cout << "I'm gonna win! Today!\n2022-04-23";
return 0;
}
L1-2 种钻石
2019年10月29日,中央电视台专题报道,中国科学院在培育钻石领域,取得科技突破。科学家们用金刚石的籽晶片作为种子,利用甲烷气体在能量作用下形成碳的等离子体,慢慢地沉积到钻石种子上,一周“种”出了一颗 1 克拉大小的钻石。
本题给出钻石的需求量和人工培育钻石的速度,请你计算出货需要的时间。
输入格式:
输入在一行中给出钻石的需求量 N(不超过 107 的正整数,以微克拉为单位)和人工培育钻石的速度 v(1≤v≤200,以微克拉/天为单位的整数)。
输出格式:
在一行中输出培育 N 微克拉钻石需要的整数天数。不到一天的时间不算在内。
输入样例:
102000 130
输出样例:
784
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a,b;
cin >> a >> b;
cout << a / b;
return 0;
}
L1-3 谁能进图书馆
为了保障安静的阅读环境,有些公共图书馆对儿童入馆做出了限制。例如“12 岁以下儿童禁止入馆,除非有 18 岁以上(包括 18 岁)的成人陪同”。现在有两位小/大朋友跑来问你,他们能不能进去?请你写个程序自动给他们一个回复。
输入格式:
输入在一行中给出 4 个整数:
禁入年龄线 陪同年龄线 询问者1的年龄 询问者2的年龄
这里的禁入年龄线是指严格小于该年龄的儿童禁止入馆;陪同年龄线是指大于等于该年龄的人士可以陪同儿童入馆。默认两个询问者的编号依次分别为 1 和 2;年龄和年龄线都是 [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:
12 18 18 8
输出样例 1:
18-Y 8-Y
qing 1 zhao gu hao 2
输入样例 2:
12 18 10 15
输出样例 2:
10-N 15-Y
2: huan ying ru guan
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a,b,c,d;
cin >> a >> b >> c >> d;
if(c >= a && d >= a) printf("%d-Y %d-Y\nhuan ying ru guan",c,d);
else if(c < a && d < a) printf("%d-N %d-N\nzhang da zai lai ba",c,d);
else if(c >= b) printf("%d-Y %d-Y\nqing 1 zhao gu hao 2",c,d);
else if(d >= b) printf("%d-Y %d-Y\nqing 2 zhao gu hao 1",c,d);
else if(c >= a && d < a) printf("%d-Y %d-N\n1: huan ying ru guan",c,d);
else if(c < a && d >= a) printf("%d-N %d-Y\n2: huan ying ru guan",c,d);
return 0;
}
L1-4 拯救外星人
你的外星人朋友不认得地球上的加减乘除符号,但是会算阶乘 —— 正整数 N 的阶乘记为 “N!”,是从 1 到 N 的连乘积。所以当他不知道“5+7”等于多少时,如果你告诉他等于“12!”,他就写出了“479001600”这个答案。
本题就请你写程序模仿外星人的行为。
输入格式:
输入在一行中给出两个正整数 A 和 B。
输出格式:
在一行中输出 (A+B) 的阶乘。题目保证 (A+B) 的值小于 12。
输入样例:
3 6
输出样例:
362880
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a,b,sum = 1;
cin >> a >> b;
int n = a + b;
for(int i=1;i<=n;i++)
sum *= i;
cout << sum;
return 0;
}
L1-5 试试手气
我们知道一个骰子有 6 个面,分别刻了 1 到 6 个点。下面给你 6 个骰子的初始状态,即它们朝上一面的点数,让你一把抓起摇出另一套结果。假设你摇骰子的手段特别精妙,每次摇出的结果都满足以下两个条件:
1、每个骰子摇出的点数都跟它之前任何一次出现的点数不同;
2、在满足条件 1 的前提下,每次都能让每个骰子得到可能得到的最大点数。
那么你应该可以预知自己第 n 次(1≤n≤5)摇出的结果。
输入格式:
输入第一行给出 6 个骰子的初始点数,即 [1,6] 之间的整数,数字间以空格分隔;第二行给出摇的次数 n(1≤n≤5)。
输出格式:
在一行中顺序列出第 n 次摇出的每个骰子的点数。数字间必须以 1 个空格分隔,行首位不得有多余空格。
输入样例:
3 6 5 4 1 4
3
输出样例:
4 3 3 3 4 3
样例解释:
这 3 次摇出的结果依次为:
6 5 6 6 6 6
5 4 4 5 5 5
4 3 3 3 4 3
#include <bits/stdc++.h>
using namespace std;
int k;
int a[10];
int main()
{
for(int i=0;i<6;i++) cin >> a[i];
cin >> k;
for(int i=0;i<6;i++)
{
if(a[i] < 6 - k + 1) a[i] = 6 - k + 1;
else a[i] = 6 - k;
}
for(int i=0;i<6;i++)
{
if(i) cout << ' ';
cout << a[i];
}
return 0;
}
L1-6 斯德哥尔摩火车上的题
上图是新浪微博上的一则趣闻,是瑞典斯德哥尔摩火车上的一道题,看上去是段伪代码:
s = ''
a = '1112031584'
for (i = 1; i < length(a); i++) {
if (a[i] % 2 == a[i-1] % 2) {
s += max(a[i], a[i-1])
}
}
goto_url('www.multisoft.se/' + s)
其中字符串的 + 操作是连接两个字符串的意思。所以这道题其实是让大家访问网站 www.multisoft.se/112358(注意:比赛中千万不要访问这个网址!!!)。
当然,能通过上述算法得到 112358 的原始字符串 a 是不唯一的。本题就请你判断,两个给定的原始字符串,能否通过上述算法得到相同的输出?
输入格式:
输入为两行仅由数字组成的非空字符串,长度均不超过 104,以回车结束。
输出格式:
对两个字符串分别采用上述斯德哥尔摩火车上的算法进行处理。如果两个结果是一样的,则在一行中输出那个结果;否则分别输出各自对应的处理结果,每个占一行。题目保证输出结果不为空。
输入样例 1:
1112031584
011102315849
输出样例 1:
112358
输入样例 2:
111203158412334
12341112031584
输出样例 2:
1123583
112358
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s1,s2,f1,f2;
cin >> s1 >> s2;
for(int i=1;i<s1.size();i++)
if(s1[i] % 2 == s1[i - 1] % 2)
f1 += max(s1[i],s1[i - 1]);
for(int i=1;i<s2.size();i++)
if(s2[i] % 2 == s2[i - 1] % 2)
f2 += max(s2[i],s2[i - 1]);
if(f1 != f2) cout << f1 << endl << f2;
else cout << f1;
return 0;
}
L1-7 机工士姆斯塔迪奥
在 MMORPG《最终幻想14》的副本“乐欲之所瓯博讷修道院”里,BOSS 机工士姆斯塔迪奥将会接受玩家的挑战。
你需要处理这个副本其中的一个机制:N×M 大小的地图被拆分为了 N×M 个 1×1 的格子,BOSS 会选择若干行或/及若干列释放技能,玩家不能站在释放技能的方格上,否则就会被击中而失败。
给定 BOSS 所有释放技能的行或列信息,请你计算出最后有多少个格子是安全的。
输入格式:
输入第一行是三个整数 N,M,Q (1≤N×M≤105,0≤Q≤1000),表示地图为 N 行 M 列大小以及选择的行/列数量。
接下来 Q 行,每行两个数 T i ,C i ,其中 Ti=0 表示 BOSS 选择的是一整行,Ti =1 表示选择的是一整列,Ci为选择的行号/列号。行和列的编号均从 1 开始。
输出格式:
输出一个数,表示安全格子的数量。
输入样例:
5 5 3
0 2
0 4
1 3
输出样例:
12
思路: 二维数组有个点过不去,空间会炸掉,所以我们需要使用两个一维数组,分别标记行和列,然后把没有标记过的输出就行了
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int f1[N],f2[N];
int main()
{
int n,m,q;
cin >> n >> m >> q;
while(q -- )
{
int a,b;
cin >> a >> b;
if(a == 0)
f1[b] = 1;
else
f2[b] = 1;
}
int res = 0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(!f1[i] && !f2[j]) res ++;
cout << res << endl;
return 0;
}
L1-8 静静的推荐
天梯赛结束后,某企业的人力资源部希望组委会能推荐一批优秀的学生,这个整理推荐名单的任务就由静静姐负责。企业接受推荐的流程是这样的:
只考虑得分不低于 175 分的学生;
一共接受 K 批次的推荐名单;
同一批推荐名单上的学生的成绩原则上应严格递增;
如果有的学生天梯赛成绩虽然与前一个人相同,但其参加过 PAT 考试,且成绩达到了该企业的面试分数线,则也可以接受。
给定全体参赛学生的成绩和他们的 PAT 考试成绩,请你帮静静姐算一算,她最多能向企业推荐多少学生?
输入格式:
输入第一行给出 3 个正整数:N(≤105)为参赛学生人数,K(≤5×103)为企业接受的推荐批次,S(≤100)为该企业的 PAT 面试分数线。
随后 N 行,每行给出两个分数,依次为一位学生的天梯赛分数(最高分 290)和 PAT 分数(最高分 100)。
输出格式:
在一行中输出静静姐最多能向企业推荐的学生人数。
输入样例:
10 2 90
203 0
169 91
175 88
175 0
175 90
189 0
189 0
189 95
189 89
256 100
输出样例:
8
样例解释:
第一批可以选择 175、189、203、256 这四个分数的学生各一名,此外 175 分 PAT 分数达到 90 分的学生和 189 分 PAT 分数达到 95 分的学生可以额外进入名单。第二批就只剩下 175、189 两个分数的学生各一名可以进入名单了。最终一共 8 人进入推荐名单。
思路:把得分不低于 175 分的学生并且成绩达到了该企业的面试分数线的特殊人群先进行推荐,然后分批推荐,这样就可以使推荐人数达到最大
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int a[N],b[N];
int main()
{
int n,k,s,res = 0;
map<int,int>mp;
cin >> n >> k >> s;
for(int i=0;i<n;i++) cin >> a[i] >> b[i];
for(int i=0;i<n;i++)
{
if(a[i] >= 175 && b[i] >= s)
{
a[i] = 0;
res ++;
}
if(mp[a[i]] < k && a[i] >= 175)
{
res ++;
mp[a[i]] ++;
}
}
cout << res;
return 0;
}
L2-1 插松枝
人造松枝加工场的工人需要将各种尺寸的塑料松针插到松枝干上,做成大大小小的松枝。他们的工作流程(并不)是这样的:
每人手边有一只小盒子,初始状态为空。
每人面前有用不完的松枝干和一个推送器,每次推送一片随机型号的松针片。
工人首先捡起一根空的松枝干,从小盒子里摸出最上面的一片松针 —— 如果小盒子是空的,就从推送器上取一片松针。将这片松针插到枝干的最下面。
工人在插后面的松针时,需要保证,每一步插到一根非空松枝干上的松针片,不能比前一步插上的松针片大。如果小盒子中最上面的松针满足要求,就取之插好;否则去推送器上取一片。如果推送器上拿到的仍然不满足要求,就把拿到的这片堆放到小盒子里,继续去推送器上取下一片。注意这里假设小盒子里的松针片是按放入的顺序堆叠起来的,工人每次只能取出最上面(即最后放入)的一片。
当下列三种情况之一发生时,工人会结束手里的松枝制作,开始做下一个:
(1)小盒子已经满了,但推送器上取到的松针仍然不满足要求。此时将手中的松枝放到成品篮里,推送器上取到的松针压回推送器,开始下一根松枝的制作。
(2)小盒子中最上面的松针不满足要求,但推送器上已经没有松针了。此时将手中的松枝放到成品篮里,开始下一根松枝的制作。
(3)手中的松枝干上已经插满了松针,将之放到成品篮里,开始下一根松枝的制作。
现在给定推送器上顺序传过来的 N 片松针的大小,以及小盒子和松枝的容量,请你编写程序自动列出每根成品松枝的信息。
输入格式:
输入在第一行中给出 3 个正整数:N(≤103),为推送器上松针片的数量;M(≤20)为小盒子能存放的松针片的最大数量;K(≤5)为一根松枝干上能插的松针片的最大数量。
随后一行给出 N 个不超过 100 的正整数,为推送器上顺序推出的松针片的大小。
输出格式:
每支松枝成品的信息占一行,顺序给出自底向上每片松针的大小。数字间以 1 个空格分隔,行首尾不得有多余空格。
输入样例:
8 3 4
20 25 15 18 20 18 8 5
输出样例:
20 15
20 18 18 8
25 5
思路:把所有的松针存入一个数组,定义两个指针l,r分别表示左右边界,定义一个栈来表示盒子,定义一个队列来存储每个松枝干上松针的编号,分类讨论:
1:小盒子已经满了,但推送器上取到的松针仍然不满足要求
2:小盒子中最上面的松针不满足要求,但推送器上已经没有松针了
3:手中的松枝干上已经插满了松针
以上三种情况表示开始制作下一枚松针
当l == r 并且 盒子里面没有松针的时候,结束程序
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
int main()
{
int n, m, k;
stack<int>S;
queue<int>Q;
cin >> n >> m >> k;
while (n -- )
{
int x;
cin >> x;
Q.push(x);
}
while (Q.size() || S.size()) // 元素不在栈里就在队列里面
{
int cnt = 0, last = 1010;
while (cnt < k) // 当前松枝干还可以继续插松针
{
if(S.size() && S.top() <= last) // 栈顶元素满足要求
{
cout << S.top() << ' ';
last = S.top();
S.pop();
cnt ++;
}
else if(Q.size()) // 队列有元素
{
int t = Q.front();
if(t <= last) // 队头元素满足
{
cout << t << ' ';
Q.pop();
last = t;
cnt ++;
}
else if(S.size() < m) // 栈没有满
{
S.push(t);
Q.pop();
}
else break;
}
else break;
}
cout << endl;
}
return 0;
}
L2-2 老板的作息表
新浪微博上有人发了某老板的作息时间表,表示其每天 4:30 就起床了。但立刻有眼尖的网友问:这时间表不完整啊,早上九点到下午一点干啥了?
本题就请你编写程序,检查任意一张时间表,找出其中没写出来的时间段。
输入格式:
输入第一行给出一个正整数 N,为作息表上列出的时间段的个数。随后 N 行,每行给出一个时间段,格式为:
hh:mm:ss – hh:mm:ss
其中 hh、mm、ss 分别是两位数表示的小时、分钟、秒。第一个时间是开始时间,第二个是结束时间。题目保证所有时间都在一天之内(即从 00:00:00 到 23:59:59);每个区间间隔至少 1 秒;并且任意两个给出的时间区间最多只在一个端点有重合,没有区间重叠的情况。
输出格式:
按照时间顺序列出时间表中没有出现的区间,每个区间占一行,格式与输入相同。题目保证至少存在一个区间需要输出。
输入样例:
8
13:00:00 - 18:00:00
00:00:00 - 01:00:05
08:00:00 - 09:00:00
07:10:59 - 08:00:00
01:00:05 - 04:30:00
06:30:00 - 07:10:58
05:30:00 - 06:30:00
18:00:00 - 19:00:00
输出样例:
04:30:00 - 05:30:00
07:10:58 - 07:10:59
09:00:00 - 13:00:00
19:00:00 - 23:59:59
思路:对时间表时间进行排序,用一个中间变量t来记录当前时间段的结束时间用来和上一个时间段的开始时间比较是否相等,不相等表示有空缺
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
struct node
{
int h1,h2,m1,m2,s1,s2;
int sum1,sum2;
bool operator < (const node &a)
{
if(sum1 != a.sum1) return sum1 < a.sum1;
return sum2 < a.sum2;
}
}f[N];
int main()
{
int n;
cin >> n;
for(int i=0;i<n;i++)
{
scanf("%d:%d:%d - %d:%d:%d",&f[i].h1,&f[i].m1,&f[i].s1,&f[i].h2,&f[i].m2,&f[i].s2);
f[i].sum1 = f[i].h1 * 3600 + f[i].m1 * 60 + f[i].s1;
f[i].sum2 = f[i].h2 * 3600 + f[i].m2 * 60 + f[i].s2;
}
sort(f,f + n);
int t = 0;
for(int i=0;i<n;i++)
{
int h1 = t / 3600,m1 = (t % 3600) / 60,s1 = t % 60;
int h2 = f[i].sum1 / 3600,m2 = (f[i].sum1 % 3600) / 60,s2 = f[i].sum1 % 60;
if(t != f[i].sum1) printf("%02d:%02d:%02d - %02d:%02d:%02d\n",h1,m1,s1,h2,m2,s2);
t = f[i].sum2;
}
int h1 = t / 3600,m1 = (t % 3600) / 60,s1 = t % 60;
if(t != 23 * 3600 + 59 * 60 + 59) printf("%02d:%02d:%02d - 23:59:59\n",h1,m1,s1);
return 0;
}
L2-3 龙龙送外卖
龙龙是“饱了呀”外卖软件的注册骑手,负责送帕特小区的外卖。帕特小区的构造非常特别,都是双向道路且没有构成环 —— 你可以简单地认为小区的路构成了一棵树,根结点是外卖站,树上的结点就是要送餐的地址。
每到中午 12 点,帕特小区就进入了点餐高峰。一开始,只有一两个地方点外卖,龙龙简单就送好了;但随着大数据的分析,龙龙被派了更多的单子,也就送得越来越累……
看着一大堆订单,龙龙想知道,从外卖站出发,访问所有点了外卖的地方至少一次(这样才能把外卖送到)所需的最短路程的距离到底是多少?每次新增一个点外卖的地址,他就想估算一遍整体工作量,这样他就可以搞明白新增一个地址给他带来了多少负担。
输入格式:
输入第一行是两个数 N 和 M (2≤N≤105 , 1≤M≤105),分别对应树上节点的个数(包括外卖站),以及新增的送餐地址的个数。
接下来首先是一行 N 个数,第 i 个数表示第 i 个点的双亲节点的编号。节点编号从 1 到 N,外卖站的双亲编号定义为 −1。
接下来有 M 行,每行给出一个新增的送餐地点的编号 Xi
。保证送餐地点中不会有外卖站,但地点有可能会重复。
为了方便计算,我们可以假设龙龙一开始一个地址的外卖都不用送,两个相邻的地点之间的路径长度统一设为 1,且从外卖站出发可以访问到所有地点。
注意:所有送餐地址可以按任意顺序访问,且完成送餐后无需返回外卖站。
输出格式:
对于每个新增的地点,在一行内输出题目需要求的最短路程的距离。
输入样例:
7 4
-1 1 1 1 2 2 3
5
6
2
4
输出样例:
2
4
4
6
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010;
int sum, maxx;
int d[N], p[N];
int dfs(int u)
{
if(p[u] == -1 || d[u] > 0) return d[u];
// 当前点为根节点或者已经遍历过
sum ++ ;
// 当前遍历的所有点到根节点的距离之和(已经遍历过的边只会统计一次)
d[u] = dfs(p[u]) + 1;
// 当前点到根节点的距离 == 父节点到根节点的距离 + 1
return d[u];
}
int main()
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i ++ ) cin >> p[i];
while (m -- )
{
int x;
cin >> x;
maxx = max(maxx, dfs(x));
// 当前最大距离
cout << 2 * sum - maxx << endl;
}
return 0;
}
L2-4 大众情人
人与人之间总有一点距离感。我们假定两个人之间的亲密程度跟他们之间的距离感成反比,并且距离感是单向的。例如小蓝对小红患了单相思,从小蓝的眼中看去,他和小红之间的距离为 1,只差一层窗户纸;但在小红的眼里,她和小蓝之间的距离为 108000,差了十万八千里…… 另外,我们进一步假定,距离感在认识的人之间是可传递的。例如小绿觉得自己跟小蓝之间的距离为 2,则即使小绿并不直接认识小红,我们也默认小绿早晚会认识小红,并且因为跟小蓝很亲近的关系,小绿会觉得自己跟小红之间的距离为 1+2=3。当然这带来一个问题,如果小绿本来也认识小红,或者他通过其他人也能认识小红,但通过不同渠道推导出来的距离感不一样,该怎么算呢?我们在这里做个简单定义,就将小绿对小红的距离感定义为所有推导出来的距离感的最小值。
一个人的异性缘不是由最喜欢他/她的那个异性决定的,而是由对他/她最无感的那个异性决定的。我们记一个人 i 在一个异性 j 眼中的距离感为 Dij;将 i 的“异性缘”定义为 1/maxj∈S(i) {Dij},其中 S(i) 是相对于 i 的所有异性的集合。那么“大众情人”就是异性缘最好(值最大)的那个人。
本题就请你从给定的一批人与人之间的距离感中分别找出两个性别中的“大众情人”。
输入格式:
输入在第一行中给出一个正整数 N(≤500),为总人数。于是我们默认所有人从 1 到 N 编号。
随后 N 行,第 i 行描述了编号为 i 的人与其他人的关系,格式为:
性别 K 朋友1:距离1 朋友2:距离2 …… 朋友K:距离K
其中 性别 是这个人的性别,F 表示女性,M 表示男性;K(<N 的非负整数)为这个人直接认识的朋友数;随后给出的是这 K 个朋友的编号、以及这个人对该朋友的距离感。距离感是不超过 106的正整数。
题目保证给出的关系中一定两种性别的人都有,不会出现重复给出的关系,并且每个人的朋友中都不包含自己。
输出格式:
第一行给出自身为女性的“大众情人”的编号,第二行给出自身为男性的“大众情人”的编号。如果存在并列,则按编号递增的顺序输出所有。数字间以一个空格分隔,行首尾不得有多余空格。
输入样例:
6
F 1 4:1
F 2 1:3 4:10
F 2 4:2 2:2
M 2 5:1 3:2
M 2 2:2 6:2
M 2 3:1 2:5
输出样例:
2 3
4
今天的文章2022年团体程序设计天梯赛决赛题解_计算机设计大赛2024分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/62525.html