预备知识:
- cctype头文件使用方法(这是一个与字符处理有关的头文件,它包含了一系列用于检测和转换单个字符的函数)
- 字符(char/string)与整型(int)的相互转换
题目翻译:
给定四个不规则字符串(如下):
破解前:3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hyscvnm
破解后:Thursday 14:04
给定四个不规则字符串,按如下规则破解其中的信息:
- 前两字符串中第1对相同的大写英文字母(区分大小写)是第字母表的第4个字母D,代表星期四;
- 第2对相同的字符是E,E是字母表的第5个英文字母,代表一天里的第14(9+5)个小时(一天的0点到23点分别由数字0到9、以及大写字母A到N表示);
- 最后两字符串第1对相同的英文字母s出现在第4个位置(从0开始计数),代表第4分钟。
输入格式:
每个输入文件包含一个测试用例。每种情况给出四个不超过60个字符的非空字符串,每行一个字符串,字符串中没有空格。
输出格式:
每个输入文件包含一个测试用例。需要按照 DAY HH:MM 的格式输出。其中,DAY星期单词的缩写,MON 对应星期一,TUE 对应星期二,WED 对应星期三,THU 对应星期四,FRI 对应星期五,SAT 对应星期六,SUN 对应星期天。(且保证每一种输入都只有唯一的一个结果)
输入样例:
3485djDkxh4hhGE
2984akDfkkkkggEdsb
s&hgsfdk
d&Hyscvnm
输出样例:
THU 14:04
思路分析:
字符串处理题,整体思路如下:
- 分三次找出对应字符串内重复的字母(分别代表星期、小时和分钟)
- 输出字母对应位置所代表的含义,输出时可以采用以下方法:
星期:用数组做映射,例如:字母 “A” 代表 “MON”(星期一),对应数组的第一个元素,也就是 [0] 号下标;字母 “D” 代表 “THU” (星期四),对应数组的第四个元素,也就是 [3] 号下标。使用字符串减法可以直接得出数组对应的下标。
小时:如果是数字,代表小时是 “0-9” 中的一个,需要在单个数字前补零;如果是字母,说明是 “10-24”中的一个,需要计算出当前是第几个大写字母,再给计算结果加上10。
分钟:满足第三个匹配规则的重复字母位置的下标即是分钟数。
如果你已经看到这里,但是自己的代码还没有通过。
建议按照上面的思路先写一遍再继续往下看~
参考代码
这里参考了柳神的代码
并附上了详细注释:
#include <iostream>
#include <cctype>
using namespace std;
int main() {
string a, b, c, d;
cin >> a >> b >> c >> d;
char t[2]; // t[0]代表星期 t[1]代表小时
int pos, i = 0, j = 0; // pos代表分钟同时是满足第三个匹配规则的位置下标
// 遍历前两个字符串
// 匹配规则一:星期
while(i < a.length() && i < b.length()) {
if (a[i] == b[i] && (a[i] >= 'A' && a[i] <= 'G')) {
t[0] = a[i];
break;
}
i++;
}
// 继续遍历前两个字符串
// 匹配规则二:小时
i = i + 1;
while (i < a.length() && i < b.length()) {
if (a[i] == b[i] && ((a[i] >= 'A' && a[i] <= 'N') || isdigit(a[i]))) { // 数字和字母均可
t[1] = a[i];
break;
}
i++;
}
// 匹配规则三:分钟
while (j < c.length() && j < d.length()) {
if (c[j] == d[j] && isalpha(c[j])) {
pos = j;
break;
}
j++;
}
// 建立星期的数组映射数组
string week[7] = {"MON ", "TUE ", "WED ", "THU ", "FRI ", "SAT ", "SUN "};
int m = isdigit(t[1]) ? t[1] - '0' : t[1] - 'A' + 10; // 计算字母所代表的小时数
cout << week[t[0]-'A']; // t[0]与week数组匹配,计算字母所代表的星期数并输出
printf("%02d:%02d", m, pos); // 输出剩余答案
return 0;
}
全部通过