题目粗心:
实现火星文和地球文的互相转化
算法思路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那样,每次都进行解决。
建设十进制数和火星文的一一映射的办法:
首先应用MarsToDecimal
和DecimalToMars
别离保留火星文到十进制数和十进制数到火星文的映射,对于任意一个不超过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;}