PAT乙级B1014 福尔摩斯的约会 (20 分)

大侦探福尔摩斯接到一张奇怪的字条:我们约会吧! 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

由于没有办法弄到后台oj的数据,但是根据我思考的过程出现的一些小障碍,总结一下这个题目的一些关键点:
1、三个条件中每一个都对于字符有一定要求,可以单独讨论
2、在前两个字符串中同时筛选两个相同的字符,这个时候可以是用不同方式进行筛选。可以选定一个包含两个元素的数组,当第一个元素找到时候就将标记值++;或者将遍历从中间分断,找到第一个相同元素后结束前半部分遍历,从下一个字符开始重新遍历。
3、对于数字输出格式的判定,虽然printf在一定程度上比cout方便很多,而且不会因为每次都重新刷新缓冲区buffer而造成时间上的浪费,而且printf的格式比cout更加灵活多变。但是编写一个简单的函数就能替代格式上的便利,时间开销就见仁见智了,我还是倾向优化算法去减少时间开销。
4、题目中那句“保证每组输入都有唯一解”这句话坑坏我了,搞得我第一个判断直接让大写字母范围保证A-Z了,找了半天换成A-G就合题意了,笑死。

以下是代码实现:
#include
using namespace std;
#include

string week[7] = { “MON”,“TUE”,“WED”,“THU”,“FRI”,“SAT”,“SUN” };

//判断str1和str2中第一个出现的大写字母
bool UpWordJudgd(char a, char b);

//寻找第二个相同的字符
bool theSecondChar(char a, char b);

//第二个字符的范围限定
bool theSecondRange(char a);

//字符串的对应转化
char CharacterChange(char a);

//输出格式
void Print(int n);

//第三个字符的范围限定
bool theThirdRange(char a);

int main()
{
/*输入样例:
3485djDkxh4hhGE
2984akDfkkkkggEdsb
s&hgsfdk
d&Hyscvnm
输出样例:THU 14:04 DAY HH:MM
*/

string str1, str2, str3, str4;
cin >> str1 >> str2 >> str3 >> str4;
int signal = 0;		//标志位,一旦前两串字符串中找到了对应的英文字母,将开始寻找另一对相同的字符

char res1 = 'A';					//用来存储第1个相同字符
char res2 = 'A';					//用来存储第2个相同字符
unsigned int res3 = 0;		//用来存储第3个相同字符的位置


for (unsigned int i = 0; i < str1.size() && i < str2.size(); i++)
{
	if (UpWordJudgd(str1[i], str2[i]))
	{
		signal = i;
		res1 = str1[i];
		break;
	}
}

for (unsigned int i = signal + 1; i < str1.size() && i < str2.size(); i++)
{
	if (theSecondChar(str1[i], str2[i]))
	{
		res2 = str1[i];
		break;
	}
}

for (unsigned int i = 0; i < str3.size() && i < str4.size(); i++)
{
	if (str3[i] == str4[i]&&theThirdRange(str3[i]))
	{
		res3 = i;
		break;
	}
}

int pro_res1 = res1 - 'A' ;
int pro_res2 = CharacterChange(res2);

//	输出样例:THU 14:04 DAY HH:MM

cout << week[pro_res1] << " ";
Print(pro_res2);
cout << ":";
Print(res3);


return 0;

}

//判断str1和str2中第一个出现的大写字母
bool UpWordJudgd(char a, char b)
{
/*
if (a < ‘A’ || a>‘Z’|| b < ‘A’ || b>‘Z’)
return false;
if (a != b) return false;
return true;
*/
if (a >= ‘A’ && a <= ‘G’ && a == b)
return true;
return false;
}

//寻找第二个相同的字符
bool theSecondChar(char a, char b)
{
if (theSecondRange(a) && a == b)
return true;
return false;
}

//第二个字符的范围限定
bool theSecondRange(char a)
{
if (a >= ‘0’ && a <= ‘9’)
return true;
else if (a >= ‘A’ && a <= ‘N’)
return true;
return false;
}

//字符串的对应转化
char CharacterChange(char a)
{
if (a >= ‘0’ && a <= ‘9’)
return a - ‘0’;
return a - ‘A’ + 10;
}

//输出格式
void Print(int n)
{
if (n < 10)
cout << “0” << n;
else
cout << n;
}

//第三个字符的范围限定
bool theThirdRange(char a)
{
if (a >= ‘a’ && a <= ‘z’) return true;
if (a >= ‘A’ && a <= ‘Z’) return true;
return false;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虐鼠无情麻子刘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值