1044 火星数字 (20 分)

题目:1044 火星数字 (20 分)

火星人是以 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(<),随后 N 行,每行给出一个 [0, 169) 区间内的数字 —— 或者是地球文,或者是火星文。

输出格式:

对应输入的每一行,在一行中输出翻译后的另一种语言的数字。

输入样例:

4
29
5
elo nov
tam

输出样例:

hel mar
may
115
13

思路:

  • 地球数字对应的火星文开数组对应下标进行利用
  • 判断是地球文还是火星文。可以根据第一位字符判断,如果是数字字符那就是数字字符串的地球文,否则就是火星文。或者用C++函数库中cctype头文件中包含的isdigit()函数判断是不是十进制的字符。
  • 若是地球文则要将字符类型转换为整型int,可以用stoi()函数,也可以用stringstream类型,但据说stoi不是一个函数库,最好少用。
    注意:如果是0, 输出tret好像会自动换行,不知道为什么,应该是我的代码的问题,看别人的好像都不会。这个点是在测试点1,我格式错误了,所以就直接特判了。
    注意13开始就是高位数了!
  • 若是火星文,凭借有无空格区分两个火星数字,然后将得到的数字进行进制转换。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cctype>  //isdigit()
 4 #include <iostream>
 5 #include <sstream>  //包含stringstream
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <string>  //stoi()
 9 #include <stack>
10 #include <queue>
11 #include <vector>
12 #include <map>
13 using namespace std;
14 
15 int main()
16 {
17     int n;
18     char low[13][5]={"tret","jan","feb","mar","apr","may","jun","jly","aug","sep","oct","nov","dec"};
19     char high[13][5]={"","tam","hel","maa","huh","tou","kes","hei","elo","syy","lok","mer","jou"};
20     scanf("%d", &n);
21     string s;
22       getchar();    //后面使用getline()需要在这里接收输入的回车, 否则会出错 
23     for(int i = 0; i < n; i++)
24     {
25         getline(cin, s);
26         if(s[0] >= '0' && s[0] <= '9')    //地球文-->火星文 
27         {    
28             int num;
29               stringstream ss;    
30               ss << s;
31               ss >> num;    //将num转为int类型 
32             int flag = 0;
33             if(num == 0)
34                 printf("tret");
35             if(num < 13 && num > 0)
36                 printf("%s\n", low[num]); 
37             if(num >= 13)    //如果数字大于等于13就需要输出高位
38             {
39                 printf("%s", high[num/13]);
40                 flag = 1;
41             }
42             if(num%13 == 0)  //我不加这个if语句进行处理且num会被13整除的话,在输出高位后,后面又会多出个其他字符,导致答案错误,测试点在2、4
43             {
44                 printf("\n");
45                 continue;
46             }
47             if(flag && num%13 != 0)
48             {
49                 printf(" %s\n", low[num%13]);        //在有高位的情况下,低位为零不输出
50             }            
51         }
52         else   //火星文-->地球文
53         {    
54             string s1 = "", s2 = "";
55             int m = 0, k = 0;
56             for(int i = 0; i < s.length(); i++)
57             {
58                 if(s[i] != ' ')    //以空格为分界线区分两个字符串
59                     s1 += s[i];    
60                 else
61                 {
62                     s2 = s1;  //s2是高位
63                     s1 = "";    
64                 }
65             }
66             for(int i = 0; i < 13; i++)    //因为可能没有空格,所以s1可能为高位也可能为低位
67             {    
68                 if(s1 == low[i])
69                     m = i;
70                 if(s1 == high[i])
71                     k = i;
72                 if(s2 == high[i])
73                     k=i;
74             }
75             printf("%d\n", k*13+m);
76         }
77     }
78     return 0;
79 }

 

总结:

  oj过题两种方式:一、知道测试点数据利用特判过;二、完美的AC代码,靠硬实力敲。前面那种方式类似投机取巧。

  最初不是用空格区分两个火星数字,代码就搞不好,在带有空格的字符串中可以利用空格来判断是否开始新的单词。学C的时候课本上有过这样的例子,只能怪自己大一上不好好敲代码以及不做任何总结。

  有时虽然有思路,但是代码却不能很好实现,或者比较冗长,就是代码敲的少的问题,功底薄弱。利用STL容器和各函数库可以使代码简便很多,所以总结除了题解,还应该总结下学到的STL容器和函数库的应用。

posted @ 2019-08-13 21:11  Anzer  阅读(1479)  评论(0编辑  收藏  举报