前言:
这就是目前为止PTA团体赛题库中L1的所有题目了,对于L2的题目可能在后面以一个很慢的速度更新,我可能会先转向Python爬虫的内容去学习一下, 然后可能还会做单片机方面的内容,大家也可以关注一下我的 Python爬虫 和 单片机 的专栏内容,感谢支持。
L1-097 编程解决一切
题目内容:
L1-097 编程解决一切 - 团体程序设计天梯赛-练习集
编程解决一切 —— 本题非常简单,就请你直接在屏幕上输出这句话:“Problem? The Solution: Programming.”。
输入格式:
本题没有输入。
输出格式:
在一行中输出 Problem? The Solution: Programming.
。
输入样例:
无
输出样例:
Problem? The Solution: Programming.
解题思路:
略。
C代码展示:
#include <stdio.h>int main()
{printf("Problem? The Solution: Programming.\n");return 0;
}
L1-098 再进去几个人
题目内容:
L1-098 再进去几个人 - 团体程序设计天梯赛-练习集
数学家、生物学家和物理学家坐在街头咖啡屋里,看着人们从街对面的一间房子走进走出。他们先看到两个人进去。时光流逝。他们又看到三个人出来。
物理学家:“测量不够准确。”
生物学家:“他们进行了繁殖。”
数学家:“如果现在再进去一个人,那房子就空了。”
下面就请你写个程序,根据进去和出来的人数,帮数学家算出来,再进去几个人,那房子就空了。
输入格式:
输入在一行中给出 2 个不超过 100 的正整数 A 和 B,其中 A 是进去的人数,B 是出来的人数。题目保证 B 比 A 要大。
输出格式:
在一行中输出使得房子变空的、需要再进去的人数。
输入样例:
4 7
输出样例:
3
解题思路:
略。
C代码展示:
#include <stdio.h>int main()
{int a, b;scanf("%d %d", &a, &b);printf("%d\n", b - a);return 0;
}
L1-099 帮助色盲
题目内容:
L1-099 帮助色盲 - 团体程序设计天梯赛-练习集
在古老的红绿灯面前,红绿色盲患者无法分辨当前亮起的灯是红色还是绿色,有些聪明人通过路口的策略是这样的:当红灯或绿灯亮起时,灯的颜色无法判断,但前方两米内有同向行走的人,就跟着前面那人行动,人家走就跟着走,人家停就跟着停;如果当前是黄灯,那么很快就要变成红灯了,于是应该停下来。麻烦的是,当灯的颜色无法判断时,前方两米内没有人……
本题就请你写一个程序,通过产生不同的提示音来帮助红绿色盲患者判断当前交通灯的颜色;但当患者可以自行判断的时候(例如黄灯或者前方两米内有人),就不做多余的打扰。具体要求的功能为:当前交通灯为红灯或绿灯时,检测其前方两米内是否有同向行走的人 —— 如果有,则患者自己可以判断,程序就不做提示;如果没有,则根据灯的颜色给出不同的提示音。黄灯也不需要给出提示。
输入格式:
输入在一行中给出两个数字 A 和 B,其间以空格分隔。其中 A 是当前交通灯的颜色,取值为 0 表示红灯、1 表示绿灯、2 表示黄灯;B 是前方行人的状态,取值为 0 表示前方两米内没有同向行走的人、1 表示有。
输出格式:
根据输入的状态在第一行中输出提示音:dudu
表示前方为绿灯,可以继续前进;biii
表示前方为红灯,应该止步;-
表示不做提示。在第二行输出患者应该执行的动作:move
表示继续前进、stop
表示止步。
输入样例 1:
0 0
输出样例 1:
biii
stop
输入样例 2:
1 1
输出样例 2:
-
move
解题思路:
这题主要是一个分支的条件判断的书写。
按照题目,咱们一点点看:
但当患者可以自行判断的时候(例如黄灯或者前方两米内有人),就不做多余的打扰。具体要求的功能为:当前交通灯为红灯或绿灯时,检测其前方两米内是否有同向行走的人 —— 如果有,则患者自己可以判断,程序就不做提示;如果没有,则根据灯的颜色给出不同的提示音。黄灯也不需要给出提示。
对于这里,咱们可以先按照能不能自己进行判断来分类,也就是有没有同向的人 或者 黄灯,放在代码里就是 b == 1 || a == 2 。
然后再对红灯和绿灯进行判断,在代码中也就是 a == 1 和 a == 0 输出结果。
C代码展示:
#include <stdio.h>int main()
{int a, b;scanf("%d %d", &a, &b);if (b == 1 || a == 2){printf("-\n");if (a == 1) printf("move");else printf("stop");}else{if (a == 0) printf("biii\nstop");else printf("dudu\nmove");}return 0;
}
L1-100 四项全能
题目内容:
L1-100 四项全能 - 团体程序设计天梯赛-练习集
新浪微博上有一个帖子给出了一道题:全班有 50 人,有 30 人会游泳,有 35 人会篮球,有 42 人会唱歌,有 46 人会骑车,至少有( )人四项都会。
发帖人不会做这道题,但是回帖有会做的:每一个才艺是一个技能点,一共是 30 + 35 + 42 + 46 = 153 个技能点,50 个人假设平均分配,每人都会 3 个技能那也只有 150,所以至少有 3 人会四个技能。
本题就请你写个程序来自动解决这类问题:给定全班总人数为 n,其中有 m 项技能,分别有 k1、k2、……、km 个人会,问至少有多少人 m 项都会。
输入格式:
输入在第一行中给出 2 个正整数:n(4≤n≤1000)和 m(1<m≤n/2),分别对应全班人数和技能总数。随后一行给出 m 个不超过 n 的正整数,其中第 i 个整数对应会第 i 项技能的人数。
输出格式:
输出至少有多少人 m 项都会。
输入样例:
50 4
30 35 42 46
输出样例:
3
解题思路:
这道题你可以将每个人会的某个技能看成一个元素,例如有一个人会三个技能,那就可以将他看成是三个元素。
按照这种想法,他会所有技能的人最少有的人数就是默认所有人会 m-1 个技能,剩下的就是会第 m 个技能的人,也就是会 m 项技能的人数。
但是要注意,他所有人加起来,可能会比默认所有人会 m - 1 个技能的人少,也就是相减之后会成负数。这时候当然不能输出这个答案,这时候应该输出 0 。
C代码展示:
#include <stdio.h>int main()
{int n, m, sum=0;scanf("%d %d", &n, &m);for (int i=0; i<m; i++){int a;scanf("%d", &a);sum += a;}if (sum >= n*(m-1)) printf("%d\n", sum - n*(m-1));else printf("0\n");return 0;
}
L1-101 别再来这么多猫娘了!
题目内容:
L1-101 别再来这么多猫娘了! - 团体程序设计天梯赛-练习集
以 GPT 技术为核心的人工智能系统出现后迅速引领了行业的变革,不仅用于大量的语言工作(如邮件编写或文章生成等工作),还被应用在一些较特殊的领域——例如去年就有同学尝试使用 ChatGPT 作弊并被当场逮捕(全校被取消成绩)。相信聪明的你一定不会犯一样的错误!
言归正传,对于 GPT 类的 AI,一个使用方式受到不少年轻用户的欢迎——将 AI 变成猫娘:
部分公司使用 AI 进行网络营销,网友同样乐于使用“变猫娘”的方式进行反击。注意:图中内容与题目无关,如无法看到图片不影响解题。
当然,由于训练数据里并不区分道德或伦理倾向,因此如果不加审查,AI 会生成大量的、不一定符合社会公序良俗的内容。尽管关于这个问题仍有争论,但至少在比赛中,我们还是期望 AI 能用于对人类更有帮助的方向上,少来一点猫娘。
因此你的工作是实现一个审查内容的代码,用于对 AI 生成的内容的初步审定。更具体地说,你会得到一段由大小写字母、数字、空格及 ASCII 码范围内的标点符号的文字,以及若干个违禁词以及警告阈值,你需要首先检查内容里有多少违禁词,如果少于阈值个,则简单地将违禁词替换为<censored>
;如果大于等于阈值个,则直接输出一段警告并输出有几个违禁词。
输入格式:
输入第一行是一个正整数 N (1≤N≤100),表示违禁词的数量。接下来的 N 行,每行一个长度不超过 10 的、只包含大小写字母、数字及 ASCII 码范围内的标点符号的单词,表示应当屏蔽的违禁词。
然后的一行是一个非负整数 k (0≤k≤100),表示违禁词的阈值。
最后是一行不超过 5000 个字符的字符串,表示需要检查的文字。
从左到右处理文本,违禁词则按照输入顺序依次处理;对于有重叠的情况,无论计数还是替换,查找完成后从违禁词末尾继续处理。
输出格式:
如果违禁词数量小于阈值,则输出替换后的文本;否则先输出一行一个数字,表示违禁词的数量,然后输出He Xie Ni Quan Jia!
。
输入样例1:
5
MaoNiang
SeQing
BaoLi
WeiGui
BuHeShi
4
BianCheng MaoNiang ba! WeiGui De Hua Ye Keyi Shuo! BuYao BaoLi NeiRong.
输出样例1:
BianCheng <censored> ba! <censored> De Hua Ye Keyi Shuo! BuYao <censored> NeiRong.
输入样例2:
5
MaoNiang
SeQing
BaoLi
WeiGui
BuHeShi
3
BianCheng MaoNiang ba! WeiGui De Hua Ye Keyi Shuo! BuYao BaoLi NeiRong.
输出样例2:
3
He Xie Ni Quan Jia!
输入样例3:
2
AA
BB
3
AAABBB
输出样例3:
<censored>A<censored>B
输入样例4:
2
AB
BB
3
AAABBB
输出样例4:
AA<censored><censored>
输入样例5:
2
BB
AB
3
AAABBB
输出样例5:
AAA<censored>B
(难绷,题目好长……)
解题思路:
本题大体的思路和前一篇里的L1-094 剪切粘贴 还有另一篇里的 L1-064 估值一亿的AI核心代码 这两题比较类似,然后我们的思路整体就是查找违禁词,然后替换,比较需要注意的是题目里的这句话:
从左到右处理文本,违禁词则按照输入顺序依次处理;对于有重叠的情况,无论计数还是替换,查找完成后从违禁词末尾继续处理。
然后其他的可以先再看看另外两篇的内容,再来写这个,相信是会有帮助的,虽然那两题也很麻烦。其他的可以先参考一下我的代码。
- 读取将要审查的关键词数量
n
。 - 使用
gets
函数读取n
个关键词,存入数组jin
中。 - 读取允许的最大违规次数
k
。 - 使用
gets
函数读取需要审查的长字符串s
。 - 对于每个关键词,使用
strstr
函数在长字符串s
中查找匹配项。如果找到匹配项,则进行替换,并更新违规次数cnt
。 - 如果在长字符串
s
中找到了关键词,则将其替换为"-",并更新ans
字符串。 - 如果违规次数
cnt
大于或等于k
,则输出违规次数和提示信息"He Xie Ni Quan Jia!"。 - 如果违规次数
cnt
小于k
,则输出审查后的长字符串s
,其中违规部分被替换为"<censored>"。
注意点:
对于替换词,不要选用字母或者数字,也不要用题目给的替换词,会导致重复判断,然后疯狂套娃,导致超出。
C代码展示:
#include <stdio.h>
#include <string.h>int main() {int n, k, cnt=0; // 定义变量n(关键词数量),k(允许的最大违规次数),cnt(违规次数计数器)char jin[105][20] = {0}, s[100000] = {0}, ans[100000] = {0}; // 定义关键词数组jin,原始内容字符串s,审查后内容字符串ansscanf("%d", &n); // 读取关键词数量getchar(); // 读取并丢弃换行符for (int i = 0; i < n; i++) gets(jin[i]); // 使用gets函数读取关键词scanf("%d", &k); // 读取允许的最大违规次数getchar(); // 读取并丢弃换行符gets(s); // 使用gets函数读取原始内容字符串for (int i = 0; i < n; i++) {while (1) {char *p = strstr(s, jin[i]); // 在s中查找关键词if (p == NULL) break; // 如果没有找到,跳出循环cnt++; // 违规次数加1char temp = *p; // 保存找到的关键词的第一个字符*p = '\0'; // 将关键词的第一个字符替换为字符串结束符,临时截断字符串strcpy(ans, s); // 复制s到ans*p = temp; // 恢复sstrcat(ans, "-"); // 在ans中添加"-"作为标记,需要在这里更换替换词。strcat(ans, p + strlen(jin[i])); // 在ans中添加关键词后的内容strcpy(s, ans); // 更新s为审查后的内容}}if (cnt >= k) printf("%d\nHe Xie Ni Quan Jia!\n", cnt); // 如果违规次数大于或等于k,输出违规次数和提示信息else {for (int i = 0; i < strlen(s); i++) {if (s[i] == '-') {printf("<censored>"); // 输出"<censored>"}else {printf("%c", s[i]); // 输出审查后的字符}}}return 0;
}
L1-102 兰州牛肉面
题目内容:
L1-102 兰州牛肉面 - 团体程序设计天梯赛-练习集
兰州牛肉面是历史悠久的美食,根据牛肉面的宽窄、配料的种类,可以细分为上百个不同的品种。你进到兰州的任何一家牛肉面馆,只说:“来一碗牛肉面!”就好像进到加州的咖啡馆说“来一杯咖啡”一样,会被店主人当成外星人……
本题的任务是,请你写程序帮助一家牛肉面馆的老板统计一下,他们一天卖出各种品种的牛肉面有多少碗,营业额一共有多少。
输入格式:
输入第一行给出一个正整数 N(≤100),为牛肉面的种类数量。这里为了简单起见,我们把不同种类的牛肉面从 1 到 N 编号,以后就用编号代替牛肉面品种的名称。第二行给出 N 个价格,第 i 个价格对应第 i 种牛肉面一碗的单价。这里的价格是 [0.01, 200.00] 区间内的实数,以元为单位,精确到分。
随后是一天内客人买面的记录,每条记录占一行,格式为:
品种编号 碗数
其中碗数
保证是正整数。当对应的 品种编号
为 0
时,表示输入结束。这个记录不算在内。
输出格式:
首先输出 N 行,第 i 行输出第 i 种牛肉面卖出了多少碗。最后一行输出当天的总营业额,仍然是以元为单位,精确到分。题目保证总营业额不超过 106。
输入样例:
5
4.00 8.50 3.20 12.00 14.10
3 5
5 2
1 1
2 3
2 2
1 9
0 0
输出样例:
10
5
5
0
2
126.70
解题思路:
这道题和上面的猫娘比起来真的是小菜一碟了,明明同样是15分题,但难度差的很多。
OK,咱也不废话了,简单说一下我的解题方法。
首先,是对当输入 0 0 时才停止输入这点,就需要边输入边判断。
然后,在它每次输入的类型的面的销售量进行统计,以及销售额进行累加。
最后,输出上面的数即可。
整体而言还是简单的。
注意:这里用来存单价和总营业额的参数类型一定要是double型,否则它可能会因为精度原因过不了测试点三。
C代码展示:
#include <stdio.h>int main()
{int n, _n, cnt, earn[105]={0};double price[105]={0}, sum=0;scanf("%d", &n);for (int i = 1; i <= n; i++) scanf("%lf", &price[i]);scanf("%d %d", &_n, &cnt);while (!(_n == 0 && cnt == 0)){ //边输入边判断。earn[_n] += cnt; //销售数量统计sum += cnt * price[_n]; //销售额累加scanf("%d %d", &_n, &cnt);}for (int i = 1; i <= n; i++){printf("%d\n", earn[i]); //输出每种类型的销售数量。}printf("%.2lf", sum); //输出销售额。return 0;
}
L1-103 整数的持续性
题目内容:
L1-103 整数的持续性 - 团体程序设计天梯赛-练习集
从任一给定的正整数 n 出发,将其每一位数字相乘,记得到的乘积为 n1。以此类推,令 ni+1 为 ni 的各位数字的乘积,直到最后得到一个个位数 nm,则 m 就称为 n 的持续性。例如 679 的持续性就是 5,因为我们从 679 开始,得到 6×7×9=378,随后得到 3×7×8=168、1×6×8=48、4×8=32,最后得到 3×2=6,一共用了 5 步。
本题就请你编写程序,找出任一给定区间内持续性最长的整数。
输入格式:
输入在一行中给出两个正整数 a 和 b(1≤a≤b≤109 且 (b−a)<103),为给定区间的两个端点。
输出格式:
首先在第一行输出区间 [a,b] 内整数最长的持续性。随后在第二行中输出持续性最长的整数。如果这样的整数不唯一,则按照递增序输出,数字间以 1 个空格分隔,行首尾不得有多余空格。
输入样例:
500 700
输出样例:
5
679 688 697
解题思路:
对于这道题,题目要求的数据量其实没有那么大,所以正常的暴力解法就能解决问题,然后它主要就是在做两件事情:
1.逐位相乘。
2.记录最长持续性和数据。
测试点1:需要注意的是对于本身就是个位数的值要注意以下,如果你的代码不能处理这部分,需要进行一定的修改。
C代码展示:
#include <stdio.h>int main()
{int a, b, max=0, ans[10000]={0}, k=0;scanf("%d %d", &a, &b);for (int i=a; i<=b; i++){ int cnt=0, num=i, temp=1;for(; num >= 10; cnt++, temp=1){ //判断这个数还能不能继续进行处理。for (; num > 0; num/=10){ //逐位相乘。temp *= num%10;}num = temp;}if (cnt > max){ //找最长的值k=1;max = cnt;ans[0] = i;}else if (cnt == max){ans[k] = i; //将数据记录下来k++;}}printf("%d\n", max);for (int i = 0; i < k; i++){if (i == 0) printf("%d", ans[i]);else printf(" %d", ans[i]);}return 0;
}
L1-104 九宫格
题目内容:
L1-104 九宫格 - 团体程序设计天梯赛-练习集
九宫格是一款数字游戏,传说起源于河图洛书,现代数学中称之为三阶幻方。游戏规则是:将一个 9×9 的正方形区域划分为 9 个 3×3 的正方形宫位,要求 1 到 9 这九个数字中的每个数字在每一行、每一列、每个宫位中都只能出现一次。
本题并不要求你写程序解决这个问题,只是对每个填好数字的九宫格,判断其是否满足游戏规则的要求。
输入格式:
输入首先在第一行给出一个正整数 n(≤10),随后给出 n 个填好数字的九宫格。每个九宫格分 9 行给出,每行给出 9 个数字,其间以空格分隔。
输出格式:
对每个给定的九宫格,判断其中的数字是否满足游戏规则的要求。满足则在一行中输出 1,否则输出 0。
输入样例:
3
5 1 9 2 8 3 4 6 7
7 2 8 9 6 4 3 5 1
3 4 6 5 7 1 9 2 8
8 9 2 1 4 5 7 3 6
4 7 3 6 2 8 1 9 5
6 5 1 7 3 9 2 8 4
9 3 4 8 1 6 5 7 2
1 6 7 3 5 2 8 4 9
2 8 5 4 9 7 6 1 3
8 2 5 4 9 7 1 3 6
7 9 6 5 1 3 8 2 4
3 4 1 6 8 2 7 9 5
6 8 4 2 7 1 3 5 9
9 1 2 8 3 5 6 4 7
5 3 7 9 6 4 2 1 8
2 7 9 1 5 8 4 6 3
4 5 8 3 2 6 9 7 1
1 6 3 7 4 9 5 8 3
81 2 5 4 9 7 1 3 6
7 9 6 5 1 3 8 2 4
3 4 1 6 8 2 7 9 5
6 8 4 2 7 1 3 5 9
9 1 2 8 3 5 6 4 7
5 3 7 9 6 4 2 1 8
2 7 9 1 5 8 4 6 3
4 5 8 3 2 6 9 7 1
1 6 3 7 4 9 5 8 2
输出样例:
1
0
0
解题思路:
这道题主要是一个记录是否重复出现的问题,然后我们在输入后,对行,列,宫三者分别进行判断即可。
- 读取将要验证的数独解的数量
n
。 - 对于每个数独解,读取9x9的矩阵
s
。 - 使用矩阵
h
、l
和g
来检查每行、每列和每个宫中的数字是否唯一。 - 如果在任何检查中发现重复的数字,将
flag
设置为0,表示数独解无效。 - 输出每个数独解的有效性。
C代码展示:
#include <stdio.h>int main() {int n; // 定义变量n,用于存储将要验证的数独解的数量scanf("%d", &n); // 读取数独解的数量for (int i = 0; i < n; i++) { // 循环处理每个数独解int s[10][10] = {{0}}, h[10][10] = {{0}}, l[10][10] = {{0}}, g[10][10] = {{0}}, flag = 1; // 定义四个9x9的矩阵s、h、l和g,并初始化为0,flag用于标记数独解是否有效for (int j = 0; j < 9; j++) { // 读取数独矩阵for (int k = 0; k < 9; k++) {scanf("%d", &s[j][k]); // 读取数独矩阵的每个元素if (s[j][k] > 9 || s[j][k] < 1) flag = 0; // 检查数字是否在1到9之间}}// 行判断for (int j = 0; j < 9 && flag == 1; j++) { // 遍历每行for (int k = 0; k < 9 && flag == 1; k++) { // 遍历每列if (h[j][s[j][k]]) flag = 0; // 检查该数字是否已在当前行出现过h[j][s[j][k]] = 1; // 标记该数字在当前行已出现}}// 列判断for (int j = 0; j < 9 && flag == 1; j++) { // 遍历每列for (int k = 0; k < 9 && flag == 1; k++) { // 遍历每行if (l[k][s[j][k]]) flag = 0; // 检查该数字是否已在当前列出现过l[k][s[j][k]] = 1; // 标记该数字在当前列已出现}}// 宫判断for (int j = 0; j < 9 && flag == 1; j++) { // 遍历每个宫的行for (int k = 0; k < 9 && flag == 1; k++) { // 遍历每个宫的列int x = j / 3 * 3 + k / 3; // 计算宫的索引if (g[x][s[j][k]]) flag = 0; // 检查该数字是否已在当前宫出现过g[x][s[j][k]] = 1; // 标记该数字在当前宫已出现}}printf("%d\n", flag); // 输出数独解是否有效(1表示有效,0表示无效)}return 0;
}
//由于行列宫的判断是基本一致的,所以我们可以同时进行,然后一下是我精炼之后的代码
#include <stdio.h>
#include <string.h>int main(){int n;scanf("%d", &n);for (int i=0; i<n; i++){int flag=1, h[3][10][10]={{{0}}};for (int j=1;j<=9;j++){for (int k=1;k<=9;k++){int x;scanf("%d", &x);if (x > 9 || x < 1) flag=0;else {int g=(j-1)/3*3+(k-1)/3;if (h[0][j][x]||h[1][k][x]||h[2][g][x]) flag=0;else {h[0][j][x]=h[1][k][x]=h[2][g][x]=1;}}}}printf("%d\n", flag);}return 0;
}