1014. 福尔摩斯的约会 (20)
原题: https://www.patest.cn/contests/pat-b-practise/1014
题意理解: 题目中关键的就3句话, 并且题目保证输入有唯一解, 因此我们不考虑特殊情况.
(1) 因为前面两字符串中第1对相同的大写英文字母(大小写有区分)是第4个字母'D',代表星期四
这句话说明, 前两个字符串开头一定会出现一对相等的大写字母, 而且必须在A-G之间
(2) 第2对相同的字符是'E',那是第5个英文字母,代表一天里的第14个钟头
这句话说明第2次出现的相等的字符必定在0-9, A-N之间, 字母必须大写
(3) 后面两字符串第1对相同的英文字母's'出现在第4个位置(从0开始计数)上,代表第4分钟
这句话说明后两个字符串, 第一次相等的时候一定是个大写或小写字母, 根据出现的位置, 判断
分钟, 范围是0-59
实现思路: 首先4行分别保存在4个字符数组里, 然后按照要求进行响应的遍历. 注意及时使用break
不要做多余的判断, 否则可能会出现某些问题. 结果字符串每一位都是固定的, 直接写死处理即可.
完整实现:
#include <stdio.h>
// res[10]存放说明
// 0 1 2, 星期
// 3, 空格
// 4 5, 小时
// 6, :
// 7 8, 分钟
// 9, '\0'
void getDay (char str[], char ch);
void getHour (char res[10], int posHour);
void getMinute (char res[10], int minute);
int main () {
char hours[24] = {
'0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'A', 'B',
'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N'
}; // 0点至23点
char line1[61];
char line2[61];
char line3[61];
char line4[61];
char res[10]; // 结果字符串
int posDay; // 前两个字符串, 第1次相等的下标
int posHour; // 前两个字符串, 第2次相等的下标
int dayFlag = 0; // 0表示posDay没值
int minute; // 存放分钟
int i = 0;
scanf("%s", line1);
scanf("%s", line2);
scanf("%s", line3);
scanf("%s", line4);
// 遍历前两个字符串, 解出星期和小时
while (i < 60) {
if (dayFlag == 0) {
// 星期是大写字母A-G
if (line1[i] >= 'A' && line1[i] <= 'G') {
// 第1次大写字母相等
if (line1[i] == line2[i]) {
posDay = i;
dayFlag = 1;
//printf("1 %c\n", line1[i]);
}
}
} else {
// 小时可能是数字或大写字母A-N
if ( (line2[i] >= 'A' && line2[i] <= 'N')
|| (line2[i] >= '0' && line2[i] <= '9') ) {
if (line1[i] == line2[i]) {
posHour = i;
//printf("2 %c\n", line1[i]);
break;
}
}
}
i++;
}
// 小时字符转数字
for (i=0; i<24; i++) {
if (hours[i] == line1[posHour]) {
posHour = i;
break; // 这个break异常关键, 卡了我2小时
// fuck beautiful, 怎么看怎么觉得这儿专门
// 做了个坑, 等着我踩呢
// 自己做个测试, 输出 00:00, 就知道坑在哪了
}
}
// 遍历后面两个字符串, 拿到分钟
// 这个字符, 即可能是大写英文字母, 也可能是小写英文字母
i = 0;
while (i < 60) {
if ( (line3[i] >= 'A' && line3[i] <= 'Z')
|| (line3[i] >= 'a' && line3[i] <= 'z')
|| (line4[i] >= 'a' && line4[i] <= 'z')
|| (line4[i] >= 'A' && line4[i] <= 'Z') ) {
if (line3[i] == line4[i]) {
minute = i;
break; // 只需要第一次
}
}
i++;
}
getDay(res, line1[posDay]);
getHour(res, posHour);
getMinute (res, minute);
res[6] = ':'; // 直接写死, 没毛病
res[9] = '\0'; // 字符串结束标志
printf("%s\n", res);
return 0;
}
// 功能: 添加日期的时间部分
void getDay (char str[], char ch) {
switch (ch) {
case 'A':
str[0] = 'M';
str[1] = 'O';
str[2] = 'N';
str[3] = ' ';
break;
case 'B':
str[0] = 'T';
str[1] = 'U';
str[2] = 'E';
str[3] = ' ';
break;
case 'C':
str[0] = 'W';
str[1] = 'E';
str[2] = 'D';
str[3] = ' ';
break;
case 'D':
str[0] = 'T';
str[1] = 'H';
str[2] = 'U';
str[3] = ' ';
break;
case 'E':
str[0] = 'F';
str[1] = 'R';
str[2] = 'I';
str[3] = ' ';
break;
case 'F':
str[0] = 'S';
str[1] = 'A';
str[2] = 'T';
str[3] = ' ';
break;
case 'G':
str[0] = 'S';
str[1] = 'U';
str[2] = 'N';
str[3] = ' ';
break;
}
}
// 小时数字, 转小时字符串, 并插入到结果字符串中4 ,5位置中
// 小时只可能是一位数, 或两位数
void getHour (char res[10], int posHour) {
int m1; // 十位
int m2; // 各位
if (posHour <= 9) {
res[4] = '0';
res[5] = (char)(posHour + '0');
} else {
m1 = (int)(posHour / 10);
m2 = (int)(posHour % 10);
res[4] = (char)(m1 + '0');
res[5] = (char)(m2 + '0');
}
}
// 这个函数复用性不好, 可以考虑把res数组的下标
// 作为参数传进来, 以此实现和上个函数复用
void getMinute (char res[10], int minute) {
int m1; // 十位
int m2; // 各位
if (minute <= 9) {
res[7] = '0';
res[8] = (char)(minute + '0');
} else {
m1 = (int)(minute / 10);
m2 = (int)(minute % 10);
res[7] = (char)(m1 + '0');
res[8] = (char)(m2 + '0');
}
}
/*
星期1 MON
星期2 TUE
星期3 WED
星期4 THU
星期5 FRI
星期6 SAT
星期日 SUN
input:
3485djDkxh4hhGE
2984akDfkkkkggEdsb
s&hgsfdk
d&Hyscvnm
output:
THU 14:04
*/
版本2: 轻量版
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define LEN 10
#define LEN2 100
int main (void) {
char week[LEN][LEN] = {
"useless", "MON", "TUE", "WED",
"THU", "FRI", "SAT", "SUN"
};
char line1[LEN2];
char line2[LEN2];
char line3[LEN2];
char line4[LEN2];
int day;
int hour;
int minute;
int len;
int i;
scanf("%s", line1);
scanf("%s", line2);
scanf("%s", line3);
scanf("%s", line4);
len = strlen(line1);
// 确定星期
for (i = 0; i < len; i++) {
if (
(line1[i] >= 'A' && line1[i] <= 'G') &&
(line2[i] >= 'A' && line2[i] <= 'G') &&
(line1[i] == line2[i])
) {
day = line1[i] - 'A' + 1;
printf("%s ", week[day]);
i++;
break;
}
}
// 确定小时
for (; i < len; i++) {
if (
(line1[i] >= '0' && line1[i] <= '9') &&
(line2[i] >= '0' && line2[i] <= '9') &&
(line1[i] == line2[i])
) {
hour = line1[i] - '0';
printf("%02d:", hour);
break;
}
if (
(line1[i] >= 'A' && line1[i] <= 'N') &&
(line2[i] >= 'A' && line2[i] <= 'N') &&
(line1[i] == line2[i])
) {
hour = line1[i] - 'A' + 10;
printf("%02d:", hour);
break;
}
}
// 确定分钟
len = strlen(line3);
for (i = 0; i < len; i++) {
if (
isalpha(line3[i]) &&
isalpha(line4[i]) &&
line3[i] == line4[i]
) {
minute = i;
printf("%02d", minute);
break;
}
}
return 0;
}