PAT乙级真题
题目链接:
https://pintia.cn/problem-sets/994805260223102976/problems/994805308755394560
引入:
大侦探福尔摩斯接到一张奇怪的字条:我们约会吧! 3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hyscvnm
。大侦探很快就明白了,字条上奇怪的乱码实际上就是约会的时间星期四``14:04
,因为前面两字符串中第 1 对相同的大写英文字母(大小写有区分)是第 4 个字母 D
,代表星期四;第 2 对相同的字符是 E
,那是第 5 个英文字母,代表一天里的第 14 个钟头(于是一天的 0 点到 23 点由数字 0 到 9、以及大写字母 A
到 N
表示);后面两字符串第 1 对相同的英文字母 s
出现在第 4 个位置(从 0 开始计数)上,代表第 4 分钟。现给定两对字符串,请帮助福尔摩斯解码得到约会的时间。
输入格式:
输入在 4 行中分别给出 4 个非空、不包含空格、且长度不超过 60 的字符串。
输出格式:
在一行中输出约会的时间,格式为 DAY HH:MM
,其中 DAY
是某星期的 3 字符缩写,即 MON
表示星期一,TUE
表示星期二,WED
表示星期三,THU
表示星期四,FRI
表示星期五,SAT
表示星期六,SUN
表示星期日。题目输入保证每个测试存在唯一解。
输入样例:
3485djDkxh4hhGE
2984akDfkkkkggEdsb
s&hgsfdk
d&Hyscvnm
输出样例:
THU 14:04
分析:
本题思路上是简单的判断字符串,存储相同字符,再按要求输出
易错点分析:
① 第一个相同字符得是大写字母,且范围是A到G,而不是A到Z,所以不能单纯用isupper()
函数
② 第二个相同字符是大写字母A到N,以及数字0到9,尤其注意的是,由于判断有先后性,若将①②步写在同个循环或者函数中,需要增加限制条件,使得在执行①后才能执行②。同时,由于判断的是字符,数字0到9可以直接用isdigit()
函数
③ (s1[i] >= 'A' && s1[i] <= 'G')
是一个整体条件,需要加上括号
亮点思路:
// 1. if(cnt)
// 2. string Day[7] = {"MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"};
// cout << Day[ch[0] - 'A'] << " ";
// 3. int m = isdigit(ch[1]) ? ch[1] - '0' : ch[1] - 'A' + 10;
// 4. printf("%02d:%02d", m, minu); //%02d 输出不满的位由0补全
解题历程:
① 想写一个string函数,判断符合条件的字母或数字,再返回一个string对象,可行但是这样要返回3个对象,增加开销,故放弃
② 写一个空函数,这回想直接直接引用,修改目标string串,如下列这种形式:
string isEqualUpper(string s1, string s2, string* s3){
s3[cnt] = s1[i];
}
但是s3[cnt]处报错,查资料后发现string不可以修改某个字符,故放弃
③string不能修改,我就想改为用字符数组接收,可行
④尝试用map容器和switch写,都比较复杂,用string字符串结合ASCII码转换会相对简单
#include <iostream>
using namespace std;
void isEqualUpper(string s1, string s2, char (&ch)[2]){
int cnt = 0;
for(int i = 0; i < s1.size() && i < s2.size(); i++){ //因为i是从0开始,所以是i < s1.size()而不是i <= s1.size()
if(cnt){ //限制条件,先执行下方第一个字符判断cnt++后才执行该判断
//第二个判断放在第一个判断前面也防止了第一个判断多次执行
//字母A到N或数字0到9
if(s1[i] == s2[i] && ((s1[i] >= 'A' && s1[i] <= 'N') || isdigit(s1[i]))){
ch[cnt] = s1[i];
break;
}
}
//字母A到G
if(s1[i] == s2[i] && (s1[i] >= 'A' && s1[i] <= 'G')){
ch[cnt] = s1[i];
cnt++;
}
}
}
void isEqualAlpha(string s1, string s2, int &minu){
for(int i = 0; i < s1.size() && i < s2.size(); i++){
if(s1[i] == s2[i] && isalpha(s1[i])){ //判断是否是字母,是字母得记下下标,退出循环
minu = i;
break;
}
}
}
int main(){
string s1, s2, s3, s4;
int minu = 0;
char ch[2];
cin >> s1 >> s2 >> s3 >> s4;
isEqualUpper(s1, s2, ch);
isEqualAlpha(s3, s4, minu);
string Day[7] = {"MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"};
int m = isdigit(ch[1]) ? ch[1] - '0' : ch[1] - 'A' + 10;//数字从0时开始;而字母从10时开始,故减去'A'的同时要再加10
//输出
cout << Day[ch[0] - 'A'] << " ";
printf("%02d:%02d", m, minu); //%02d 输出不满的位由0补全
system("pause");
}
悄咪咪表白柳婼大佬