题目描述
People on Mars count their numbers with base 13:
Zero on Earth is called "tret" on Mars.
The numbers 1 to 12 on Earth is called "jan, feb, mar, apr, may, jun, jly, aug, sep, oct, nov, dec" on Mars, respectively.
For the next higher digit, Mars people name the 12 numbers as "tam, hel, maa, huh, tou, kes, hei, elo, syy, lok, mer, jou", respectively.
For examples, the number 29 on Earth is called "hel mar" on Mars; and "elo nov" on Mars corresponds to 115 on Earth. In order to help communication between people from these two planets, you are supposed to write a program for mutual translation between Earth and Mars number systems.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (<100). Then N lines follow, each contains a number in [0, 169), given either in the form of an Earth number, or that of Mars.
Output Specification:
For each number, print in a line the corresponding number in the other language.
Sample Input:
4
29
5
elo nov
tam
Sample Output:
hel mar
may
115
13
题目分析
进行进制的转换 10 进制 到 13 进制
如果是earth 首先变为13进制,然后对个位和十位分别调用不同的mars文字
如果是mars文字,则去查找到13进制的对应,然后再转为10进制
这里涉及到 数字到 文字的双向映射,可以使用map,如果使用数组不行,那个不能双向,map也不能双向,只能去遍历查找
如何读取一行?
代码
#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <algorithm>
#include <unordered_map>
#include <cstring>
#include <unordered_set>
#include <sstream>
using namespace std;
map<int, string> mpunit{{0, "tret"},
{1, "jan"},
{2, "feb"},
{3, "mar"},
{4, "apr"},
{5, "may"},
{6, "jun"},
{7, "jly"},
{8, "aug"},
{9, "sep"},
{10, "oct"},
{11, "nov"},
{12, "dec"}};
map<int, string> mpdecade{{0, "tret"},
{1, "tam"},
{2, "hel"},
{3, "maa"},
{4, "huh"},
{5, "tou"},
{6, "kes"},
{7, "hei"},
{8, "elo"},
{9, "syy"},
{10, "lok"},
{11, "mer"},
{12, "jou"}};
string num2str[170];
map <string ,int >str2num;
int main() {
int N;
scanf("%d", &N);
// 建立0-168与火星文之间的直接映射
for(int i=0;i<13;i++) //对于十位为0,个位直接映射
{
num2str[i]=mpunit[i];
str2num[mpunit[i]] = i;
}
for(int i=13;i<169;i++) //对于十位不为0,个位不为0
{
if(i%13==0)//说明个位为0,十位不为0
{
int decade = i/13;
num2str[i] = mpdecade[decade];
str2num[mpdecade[decade]] = i;
} else //说明个位不为0,十位不为0
{
int decade = i/13;
int unit = i%13;
num2str[i] = mpdecade[decade]+" "+mpunit[unit];
str2num[num2str[i]] = i;
}
}
string a;
string b;
string word;
cin.ignore(1);//忽略指定数量的字符,这里忽略第一个,因为cin的指针指向了开头
for (int i = 0; i < N; i++) {
getline(cin, a);
if (isdigit(a[0])) {
b = num2str[ stoi(a)] ;
cout << b << endl;
} else {
int out = str2num[a] ;
cout << out << endl;
}
}
}
思考与收获
如果直接去读取的,然后利用一个函数去转换的话比较复杂,由于值比较小,0-168,因此直接建立两者的映射关系 str2num,num2str(思考问题要到位,把这个思路吸收了)
另外在家建立映射关系的时候,是双向同时建立的
要注意13进制下十位不为0,个位为0 只用输出十位即可,十位为0,个位不为0,只用输出个位
对于一行里面有多个字符串的读取,可以使用getline(cin,str); 如果需要对其进行分割,可以使用sstream头文件下的,stringstream ss(str) 将其转为stringstream的对象,然后ss>>word即可进行分离
在使用getline中,可能会遇到第一个读入为空字符串的情况,可以使用 cin.ignore(1);来进行忽略读入