题目
火星人是以 13 进制计数的:
- 地球人的 0 被火星人称为 tret。
- 地球人数字 1 到 12 的火星文分别为:jan, feb, mar, apr, may, jun, jly, aug, sep, oct, nov, dec。
- 火星人将进位以后的 12 个高位数字分别称为:tam, hel, maa, huh, tou, kes, hei, elo, syy, lok, mer, jou。 例如地球人的数字 29 翻译成火星文就是 hel mar;而火星文 elo nov 对应地球数字 115。为了方便交流,请你编写程序实现地球和火星数字之间的互译
输入格式
输入第一行给出一个正整数 N(<100),随后 N 行,每行给出一个 [0, 169)区间内的数字 —— 或者是地球文,或者是火星文
输出格式
对应输入的每一行,在一行中输出翻译后的另一种语言的数字。
思路
有两个前置字符串数组:string low[13] = {"tret", "jan", "feb", "mar", "apr", "may", "jun", "jly", "aug", "sep", "oct", "nov", "dec"}; //0~12.低位的 string high[13] = {" ", "tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou"}; //高位
输入你想转化的数字或者火星文[输入个数n后记得geychar(),吞掉那个空格,我傻傻的找bug。老菜了],如果是数字,就去ChangeOne函数,如果是火星文,就去ChangeTwo函数。
ChangeOne,先把输入的字符串使用stoi转化为整数num,然后判定,如果num/13不为0(13进制的),那么就有高位,输出对应的high[num / 13]。在看是不是输出空格(有高位,有低位的情况)。最后有低位输出低位。 注意,因为0/13为0,所以如果是0就有问题,要进行特判。
ChangeTwo,进行一个分类,输入的是两位火星文一类,一位火星文一类,依靠字符串长度进行区分。一位火星文直接与两个字符串数组遍历对比就行了。两位火星文,就要依据空格区分为两个字符串s1,s2,进行转化。
//foreverking
#include <vector>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
string low[13] = {"tret", "jan", "feb", "mar", "apr", "may", "jun", "jly", "aug", "sep", "oct", "nov", "dec"}; //0~12.低位的
string high[13] = {" ", "tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou"}; //高位
int n;
string s;
//数字转火星,每13进1
void ChangeOne(string s){
int num = stoi(s);//转化为数字
if (num / 13 != 0)//有高位
cout << high[num / 13];
if ((num / 13 != 0) && (num % 13 != 0))//有低位,输出空格
cout << " ";
if ((num % 13 != 0) || num == 0)//输出低位的,但是注意是0的情况,0mod13是0,特判啊
cout << low[num % 13];
}
//火星转数字
void ChangeTwo(string s){
// if (s == "tret")
// cout << 0;
int len = s.size();
if (len == 3){//一位火星文
for (int i = 0; i < 13; i++){
if (low[i] == s){//
cout << i;
break; //退出
}
else if (high[i] == s){
cout << i * 13;
break; //退出
}
}
}
else{
string s1,s2;
int m = 0,k = 0;//做十位,个位
for(int j = 0; j < s.size(); j++){
if(s[j] != ' ')
s1 += s[j];//以空格为分界线区分两个字符串,s1是低位,s2是高位
else{
s2 = s1;
s1 = "";
}
}
for(int i = 0; i < 13; i++){
if(s1 == low[i]) m=i;
if(s2 == high[i]) k=i;
}
cout << k * 13 + m;
}
}
int main(){
cin >> n;
getchar();
for(int i = 0; i < n; i++){
//每行给出一个 [0, 169) 区间内的数字 —— 或者是地球文,或者是火星文,火星文有空格,使用getline
getline(cin, s);
if (s[0] >= '0' && s[0] <= '9')
ChangeOne(s);
else
ChangeTwo(s);
cout << endl; //换行
}
return 0;
}
然后,发现了ChangeTwoA没必要进行分类。依据空格分隔字符串,如果有空格,就是两位火星文,分割为s1,s2再遍历转化,没有空格,只有s1就够了。
//foreverking
#include <vector>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
string low[13] = {"tret", "jan", "feb", "mar", "apr", "may", "jun", "jly", "aug", "sep", "oct", "nov", "dec"}; //0~12.低位的
string high[13] = {" ", "tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou"}; //高位
int n;
string s;
//数字转火星,每13进1
void ChangeOne(string s){
int num = stoi(s);//转化为数字
if (num / 13 != 0)//有高位
cout << high[num / 13];
if ((num / 13 != 0) && (num % 13 != 0))//有低位,输出空格
cout << " ";
if ((num % 13 != 0) || num == 0)//输出低位的,但是注意是0的情况,0mod13是0,特判啊
cout << low[num % 13];
}
//火星转数字
void ChangeTwo(string s){
// if (s == "tret")
// cout << 0;
string s1,s2;
int m = 0,k = 0;
for(int j = 0; j < s.size(); j++){
if(s[j] != ' ')
s1 += s[j];//以空格为分界线区分两个字符串,火星文两位时,s1是低位,s2是高位。火星文是一位时,只有s1
else{
s2 = s1;
s1 = "";
}
}
for(int i = 0; i < 13; i++){//因为可能没有空格,所以s1可能为高位也可能为低位
if(s1 == low[i]) m=i;
if(s1 == high[i]) k=i;
if(s2 == high[i]) k=i;
}
cout << k * 13 + m;
}
int main(){
cin >> n;
getchar();
for(int i = 0; i < n; i++){
//每行给出一个 [0, 169) 区间内的数字 —— 或者是地球文,或者是火星文,火星文有空格,使用getline
getline(cin, s);
if (s[0] >= '0' && s[0] <= '9')
ChangeOne(s);
else
ChangeTwo(s);
cout << endl; //换行
}
return 0;
}