PTA团体程序设计天梯赛L1真题讲解L1-077-080
官网https://pintia.cn/problem-sets/994805046380707840/exam/problems/type/7
文章目录
- L1-077 大笨钟的心情
- L1-078 吉老师的回归
- L1-079 天梯赛的善良
- L1-080 乘法口诀数列
L1-077 大笨钟的心情
题目大意:输入24个整数,对应一天中0 ~ 23点每个小时的心情指数。随后有多组询问,每次给出一个时间点,若时间合法(在0~23范围内),则判断对应心情指数:大于50输出“指数 Yes”,否则输出“指数 No”;若时间不合法,直接结束程序。
核心思路:
用长度为24的数组存储每个小时的心情指数,下标直接对应小时数。随后循环读取询问的时间值,先判断是否在合法区间内:合法则根据数组对应值判断输出结果;不合法则直接终止循环,结束程序。
正解代码
#include<bits/stdc++.h>usingnamespacestd;intmain(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);inta[24];for(inti=0;i<24;i++){cin>>a[i];}intx;while(cin>>x){if(x>=0&&x<=23){if(a[x]>50)cout<<a[x]<<" Yes"<<endl;elsecout<<a[x]<<" No"<<endl;}elsereturn0;}return0;}代码实现要点:
- 数组下标与小时一一对应,输入时直接按顺序存入
a[0]到a[23]。 - 使用
while(cin >> x)持续读取输入,自动处理多组询问。 - 判断条件为
a[x] > 50,等于50时输出No。 - 遇到非法时间直接退出程序,无需处理该输入。
L1-078 吉老师的回归
题目大意:给定n道题目的题面字符串,吉老师按顺序看题,跳过所有包含小写字符串qiandao或easy的题目(区分大小写),只做其余题目。已知吉老师已经做完了m道要做的题,求他当前正在做的题目的题面;如果所有要做的题都做完了,输出Wo AK le。
核心思路:
- 遍历所有n道题目,筛选出所有**不包含
qiandao且不包含easy**的题目,按顺序存入列表,这些是吉老师会做的题。 - 统计可做题目的总数cnt:
- 若
cnt ≤ m,说明吉老师已经做完了所有可做题目,输出Wo AK le; - 若
cnt > m,说明还有题可做,做完m道后正在做的是列表中下标为m的题目,直接输出该题面即可。
- 若
正解代码
#include<iostream>#include<vector>#include<string>usingnamespacestd;intmain(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);intn,m;cin>>n>>m;cin.ignore();vector<string>a;intcnt=0;while(n--){string s;getline(cin,s);if(s.find("qiandao")==string::npos&&s.find("easy")==string::npos){a.push_back(s);cnt++;}}if(cnt<=m){cout<<"Wo AK le";}else{if(m<cnt){for(inti=m;i<cnt;i++){if(i=cnt-1)cout<<a[i];elsecout<<a[i]<<endl;}}}return0;}代码实现要点:
- 使用
string::find()函数判断子串是否存在,若返回string::npos说明不包含该子串。 - 由于
cin >> n >> m后会残留换行符,需要用cin.ignore()消耗换行,避免后续getline读取到空行。 - 筛选题目时按输入顺序存储,保证做题顺序正确。
L1-079 天梯赛的善良
题目大意:给定n个参赛学生的能力值,分别输出能力值的最小值及其出现次数、最大值及其出现次数。
核心思路:
遍历所有能力值,同步完成三个任务:更新当前最小值、更新当前最大值、统计每个能力值的出现次数。遍历完成后,直接通过最值从计数中取出对应次数,按格式输出即可。
可以使用map或数组完成计数,也可以在遍历时专门维护最小值计数、最大值计数,实现方式灵活。
正解代码
#include<bits/stdc++.h>usingnamespacestd;constintN=2e4+9;inta[N];intmain(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);map<int,int>mp;intn,ma=-1,mi=1e7;cin>>n;for(inti=0;i<n;i++){cin>>a[i];mp[a[i]]++;mi=min(mi,a[i]);ma=max(ma,a[i]);}cout<<mi<<" "<<mp[mi]<<endl;cout<<ma<<" "<<mp[ma]<<endl;return0;}代码实现要点:
- 初始化最小值为一个足够大的数(如
1e9),最大值为一个足够小的数(如-1),保证第一个数必然能更新最值。 - 使用
map<int, int>统计次数,每读入一个数就对应计数加1,同时更新最值。 - 输出分两行,第一行最小值+次数,第二行最大值+次数,数字间用空格分隔。
注意事项:
- 若所有数都相同,则最小值和最大值相等,两次输出的结果也会相同,逻辑上无需特殊处理。
- 能力值范围不大时也可用数组计数,效率更高;使用map写法更简洁通用。
L1-080 乘法口诀数列
题目大意:给定两个1位数字a1、a2作为数列前两项,按照规则生成数列:依次取相邻两项相乘,将乘积的每一位数字按顺序追加到数列末尾。输出数列的前n项。
核心思路:
用数组存储数列,前两项初始化为a1、a2。依次遍历每一对相邻数字,计算乘积后拆分为单个数字,逐个追加到数组末尾,直到数组长度达到n停止。
乘积拆分规则:若乘积是两位数,先放十位再放个位;若是一位数直接放入。每放入一个数字都要检查是否已经达到n项,避免越界。
正解代码
#include<bits/stdc++.h>usingnamespacestd;intmain(){inta1,a2,n;cin>>a1>>a2>>n;intb[1001]={a1,a2};// 初始化前两个数cout<<a1<<' '<<a2;// 先输出前两个for(inti=2,j=2;i<n&&j<n;i++){intc=b[i-1]*b[i-2];// 计算乘积if(c>=10){// 拆分成两位数if(j<n)b[j++]=c/10;if(j<n)b[j++]=c%10;}else{// 直接放入if(j<n)b[j++]=c;}}// 输出结果(前n个)for(inti=2;i<n;i++){cout<<' '<<b[i];}return0;}代码实现要点:
- 数组大小需足够容纳n项,一般开1000以上即可满足常规数据范围。
- 拆分两位数时使用
c / 10取十位、c % 10取个位,保证顺序正确。 - 每次追加数字前都判断是否已达到n项,确保不会填充超过n个元素,也避免数组越界。
- 输出时控制空格格式,首尾无多余空格。
