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