#include <bits/stdc++.h>
using namespace std;
int main() {
// 十三进制
string low[13]{"tret", "jan", "feb", "mar", "apr", "may", "jun", "jly", "aug", "sep", "oct", "nov", "dec"};
string high[13]{"","tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou"};
int n;
cin >> n;
// 避免getline吃掉换行 手动吃掉
getchar();
while(n--){
string str;
getline(cin, str);
// 首位是数字则是地球
if(isdigit(str[0])){
int num = stoi(str);
// 获得低位 和进位
int l = num % 13;
int h = num / 13 % 13;
// 高低位皆存在
if(h && l)
cout << high[h] << " " << low[l] << endl;
// 低位为0 比如 26 输出hel 低位的0忽略
else if (h)
cout << high[h] << endl;
// 高位为0
else
cout << low[l] << endl;
}
else {
int numL, numH;
// 并不是所有都是三位字符 要考虑四位字符的tret
if(str.size() > 4){
// 一位火星文的时候前面的字符串是低位
// 二位火星文的时候前面的是高位 后面的是低位
// 两个处理截断的位置不一样
string l = str.substr(4), h = str.substr(0, 3);
for(numL = 0; numL < 13 && l != low[numL]; numL++);
for(numH = 0; numH < 13 && h != high[numH]; numH++);
cout << numH * 13 + numL << endl;
}
// 一位火星文
else{
// 截断也得考虑 tret
string l = str.substr(0, 4);
for(numL = 0; numL < 13 && l != low[numL]; numL++);
for(numH = 0; numH < 13 && l != high[numH]; numH++);
// 低位为13时可能为tam 也可能是高位的元素
// 如果高位能够找到 则输出13的倍数
if(numL == 13 && numH != 13)
cout << numH * 13 << endl;
else
cout << numL << endl;
}
}
}
}
这题目要考虑的一些边界问题。样例可以看到的一个边界问题是 tam 。这个输入在低位找不到,而通过遍历的话会得到 i = 13。而 13 进制不存在 13 所以实际转换成高位的 1。
其他同理,hel = 26, maa = 39 等等。
同时反过来看到,13 求得低位的十进制为 0,高位的为 1,如果输出的话,十进制的 0 是没有转换成 tret 的。所以应该想到 13 的倍数的时候不需要输出低位的0。实际输出是tam,我们不能输出成 tam tret。这跟十进制不一样。
所以这是处理的时候需要额外考虑的两个边界情况。
还有一个是 tret 是四位的字符,其他都是三位的字符,需要额外处理一下。