PAT乙级1044

123 阅读1分钟

题目

火星人是以 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;
}

题目链接