关于算法-数据结构:PAT甲级1100-Mars-Numbers

41次阅读

共计 3521 个字符,预计需要花费 9 分钟才能阅读完成。

题目粗心:

实现火星文和地球文的互相转化

算法思路 1:

用 unit 数组保留 10 进制个位到火星文个位的映射, 用 decade 数组保留 10 进制十位到火星文 10 位的映射, 留神最大不超过 169, 阐明火星文最大 2 位,
应用 Unit 和 Decade 别离保留火星个位和十位与 10 进制的个位和十位的映射. 记得初始化!!!!!, 应用字符串承受输出的数字 (读一行), 而后判断 s[0] 是否是数字, 如果是, 就将该数字首先转化为 13 进制数,每一位用数组 t 保留, 而后判断是否只有个位或者只有十位, 如果是得只输入个位或者十位, 否则就是得先输入十位而后输入个位, 这里有个特例得特判输入就是数字 0, 输出数字 0 得输入 tret, 不然会呈现测试点 1 格局谬误, 如果 s[0]不是数字就将获取以后位的火星文对应的 10 进制数(用字符串切割), 而后将其转化为 10 进制数, 而后输入即可, 留神在火星文只有 1 位的时候得判断是个位还是十位的火星文。

算法思路 2:

同样用 unit 数组保留 10 进制个位到火星文个位的映射, 用 decade 数组保留 10 进制十位到火星文 10 位的映射,然而留神到数字最大是 168,这个数字其实算是比拟小的了,所以间接通过将 0~168 的数字和火星文建设互相一一映射,在输出的时候间接查表就能够实现输入,无需像思路 1 那样,每次都进行解决。

建设十进制数和火星文的一一映射的办法:

首先应用 MarsToDecimalDecimalToMars别离保留火星文到十进制数和十进制数到火星文的映射,对于任意一个不超过 2 位的数字,都能够看做是十位和个位的联合,对于只有 1 位的,十位看成 0 就好,(看上去是废话,其实不是)比方十进制数 13 就能够写成 10+ 3 别离是 10 的 1 倍数字和 3 的联合,25 能够写成 20+ 5 别离是 10 的 2 倍和数字 5 的联合,那么咱们能够看到,10 为进制数,是固定的数字,而 1,3 和 2,5 都理论是个位数字,能够看出对于 13 进制数,取得 168 数字的全副只须要个位数字和进制数 13 就能够实现。那么咱们就先建设个位和 13 的倍数与火星文的映射,其实就是 unit 数组和 decade 数组保留的映射关系,而后咱们应用指针 i 示意十位的数字 (25 的十位数字为 2),j 示意个位数字,都从 1 到 12 遍历,那么i*13+j 就是没有建设映射的数字,其对应的火星文为 decade[i]+""+unit[j],比方 14 对应tam jan(decade[1]+" "+unit[1])。那么保留该映射关系就是如下代码DecimalToMars[i*13+j] = decade[i]+" "+unit[j]MarsToDecimal[DecimalToMars[i*13+j]] = i*13+j

提交后果:

留神点:

1、13 的整倍数最初不要输入 tret, 比方 13 应该输入 tam 而不是 tam tret。

AC 代码 1:

#include<cstdio>
#include<string>
#include<unordered_map>
#include<cstring>
#include<iostream> 

using namespace std;

string unit[13] = {"tret","jan", "feb", "mar", "apr", "may", "jun", "jly", "aug", "sep", "oct", "nov", "dec"};// 个位
string decade[13] = {"","tam","hel","maa","huh","tou","kes","hei","elo","syy","lok","mer","jou"};// 十位

unordered_map<string,int> Unit;// 火星个位对应的 10 进制个位
unordered_map<string,int> Decade;// 火星十位对应的 10 进制十位

void init(){for(int i=0;i<13;++i){Unit[unit[i]] = i;
    }
    for(int i=1;i<13;++i){Decade[decade[i]] = i;
    }
} 

int main(){init();
    int n;
    scanf("%d%*c",&n);// 疏忽一个字符型输出项 
    for(int i=0;i<n;++i){
        string s;
        getline(cin,s);
        if(s[0]>='0'&&s[0]<='9'){// 数字, 转化为火星文 
            int t[2];// 暂存每一位数字
            memset(t,0,sizeof(t));// 初始化 t, 必须得有 
            int q = stoi(s);// 将字符串 s 转化为数字 
            if(q==0){// 输出的数字为 0 得特判输入, 测试点 1 考查, 如果不写就会使 "tret" 导致格局谬误 
                printf("tret");
                continue;
            }
            for(int i=0;q!=0;++i){// 取 q 的每一位 
                t[i] = q%13;
                q /= 13;
            }
            if(t[1]==0&&t[0]!=0){// 高位没有, 火星文只有个位 
                printf("%s\n",unit[t[0]].c_str());
            }else if(t[0]==0&&t[1]!=0){// 个位没有, 只有高位 
                printf("%s\n",decade[t[1]].c_str());
            }else{printf("%s %s\n",decade[t[1]].c_str(),unit[t[0]].c_str());
            }
        }else{// 火星文,输入数字
            if(s.size()==3){// 只有一位 
                if(Unit.find(s)!=Unit.end()){// 是个位
                    printf("%d\n",Unit[s]); 
                }else{// 是十位 
                    printf("%d\n",Decade[s]*13);// 转化为 10 进制 
                }
            }else{// 2 位火星数字 
                string s1  =s.substr(0,3);
                string s2 = s.substr(4,3);
                int r = Decade[s1]*13+Unit[s2];//// 转化为 10 进制 
                printf("%d\n",r);
            }
        }
    }
    return 0;
}

AC 代码 2:

#include <cstdio>
#include <unordered_map>
#include <string>
#include <iostream>


using namespace std;


string unit[13] = {"tret","jan", "feb", "mar", "apr", "may", "jun", "jly", "aug", "sep", "oct", "nov", "dec"};// 个位
string decade[13] = {"tret","tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou"};// 十位

unordered_map<string,int> MarsToDecimal;// 火星文到十进制数的映射
unordered_map<int,string> DecimalToMars;// 十进制数到火星文的映射

void init(){
    // 首先实现个位和 13 的倍数的映射
    for (int i = 0; i < 13; ++i) {
        // 个位
        DecimalToMars[i] = unit[i];
        MarsToDecimal[unit[i]] = i;
        // 十位
        DecimalToMars[i*13] = decade[i];
        MarsToDecimal[decade[i]] = i*13;
    }
    for (int i = 1; i < 13; ++i) {for (int j = 1; j < 13; ++j) {DecimalToMars[i*13+j] = decade[i]+" "+unit[j];
            MarsToDecimal[DecimalToMars[i*13+j]] = i*13+j;
        }
    }
}

bool isDecimal(string s){for (char i : s) {if(!(i>='0'&&i<='9')){return false;}
    }
    return true;
}


int main(){init();
    int N;
    scanf("%d",&N);
    getchar();// 排汇回车
    string s;
    for (int i = 0; i < N; ++i) {getline(cin,s);
        if(isDecimal(s)){
            // 为数字, 转化为火星文
            int num = 0;
            for (int j = 0; j < s.size(); ++j) {num = num*10+(s[j]-'0');
            }
            printf("%s\n",DecimalToMars[num].c_str());
        } else {
            // 为火星文,转化为数字
            printf("%d\n",MarsToDecimal[s]);
        }
    }
    return 0;
}

正文完
 0