题目大意:
实现火星文和地球文的相互转化
算法思路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;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。