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;
}

posted @ 2017-10-17 14:33  阿胜4K  阅读(183)  评论(0编辑  收藏  举报