【题意】
是一个10进制和13进制转换的问题。
依次给出N(<100)个输入,可能是10进制数,也可能是13进制的表示(取值为[0, 169)也就是13进制最多两位,但也可能为1位)
0到12分别在13进制中对应 “tret, jan, feb, mar, apr, may, jun, jly, aug, sep, oct, nov, dec”
但是要注意,除了最低位,更高位的数字不是用这13个,而是另外13个。
【思路】
- 输入,都按照字符串输入,如果是数字,就转成数字,否则利用一个hash数组映射成为相应的数字即可。还有就是两位的情况的处理,因为每一位都是三个字母,所以可以读取一整行再用字符串长度判断。
- 转换,简单的字符串hash即可。10进制转13进制还要多一步映射为字符串输出。
【本人代码】
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>
#include <iostream>
using namespace std;
const int maxl = 10;
map<string, int> strToInt1 = { {"tret", 0}, {"jan", 1}, {"feb", 2}, {"mar", 3}, {"apr", 4}, {"may", 5}, {"jun", 6}, {"jly", 7}, {"aug", 8}, {"sep", 9}, {"oct", 10}, {"nov", 11}, {"dec", 12} };
map<string, int> strToInt2 = { { "tam", 1 }, { "hel", 2 }, { "maa", 3 }, { "huh", 4 }, { "tou", 5 }, { "kes", 6 },{ "hei", 7 }, { "elo", 8 }, { "syy", 9 }, { "lok", 10 }, { "mer", 11 }, { "jou", 12 } };
map<int, string> intToStr1 = { {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> intToStr2 = { {1, "tam"}, {2, "hel"}, {3, "maa"}, {4, "huh"}, {5, "tou"}, {6, "kes"},{7, "hei"}, {8, "elo"}, {9, "syy"}, {10, "lok"}, {11, "mer"}, {12, "jou"} };//int hashFunc(char str[]) {
// int ans = 0;
// int len = strlen(str);
// if (str[0] >= '0' && str[0] <= '9') {
// for (int i = 0; i < len; i++) {
// ans = ans * 10 + str[i];
// }
// return ans;
// }
// else {
// if (len > 4) {
// string s1, s2;
// char str1[5], str2[5];
// sscanf(str, "%s %s", str1, str2);
// s1 = str1;
// s2 = str2;
// int h = strToInt2[s1];
// int l = strToInt1[s2];
// ans = h * 13 + l;
// return ans;
// }
// else {
// string s = str;
// return strToInt1[s];
// }
// }
//}int main() {int n; // number of test exampleschar str[maxl];scanf("%d", &n);getchar();for (int i = 0; i < n; i++){fgets(str, 10, stdin);int ans = 0;int len = strlen(str);if (str[len - 1] == '\n'){str[len - 1] = '\0';len--;}if (str[0] >= '0' && str[0] <= '9') {for (int i = 0; i < len; i++) {ans = ans * 10 + str[i] - '0';}int h = ans / 13;int l = ans % 13;if (ans < 13) {cout << intToStr1[l] << endl;}else if (ans % 13 == 0) {cout << intToStr2[h] << endl;}else if (ans % 13 != 0) {cout << intToStr2[h] << ' ' << intToStr1[l] << endl;}}else {if (len > 4) {string s1, s2;char str1[5], str2[5];sscanf(str, "%s %s", str1, str2);s1 = str1;s2 = str2;int h = strToInt2[s1];int l = strToInt1[s2];ans = h * 13 + l;cout << ans << endl;}else {string s = str;if (strToInt2[s] == 0) {cout << strToInt1[s] << endl;}else {cout << strToInt2[s]*13<< endl;}}}}
}
后三个测试点总是过不了,应该是零的情况 没有处理好。
【注意点】
这题需要注意的就是很多细节,所以最好从一开始就把一些细节想清楚,然后进行设计,否则后面会很麻烦。
- 注意到测试样例的最后一个值,它虽然本应该是高位的,但是却只有一位,所以它代表的是13的整数倍。
- 注意0的情况
- map可以考虑用unordered_map速度更快。
- 这种要自己一个个写映射关系很浪费时间,所以其实可以学习别人的做法,先直接复制题目里的元素序列初始化一个数组,再用for循环建立映射,这样省时间,而且不会输错。
- 对于Int到字符串的映射可以直接用二维数组实现。
下面是参考的别人的代码:
#include<cstdio>
#include <string>
#include <iostream>
#include<math.h>
#include<map>
using namespace std;map<string,int> mp1;
map<string,int> mp2;
int main(){int num;string a[13] = {"tret","jan", "feb", "mar", "apr", "may", "jun", "jly","aug", "sep", "oct", "nov", "dec"};string b[13] = {"tret","tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou"};for(int i=0;i<13;i++){mp1[a[i]] = i;mp2[b[i]] = i;}scanf("%d",&num);for(int i=0;i<num;i++){string s,s2;cin>>s;if( getchar() == ' '){cin>>s2;}if('0'<=s[0]&&s[0]<='9'){int l = s.length()-1;int numR = 0;for(int i=0;i<s.length();i++){numR += (s[i]-'0')*pow(10, l--);}int low = numR%13;int high = numR/13;if(high==0){cout <<a[low]<<"\n";}else if(high!=0&&low==0){cout<<b[high]<<"\n";}else{cout<<b[high]<<" "<<a[low]<<"\n";}}else{if(s2.length()==0){for(int i=0;i<13;i++){if(s==a[i]){printf("%d\n",mp1[a[i]]);break;}if(s==b[i]){printf("%d\n",mp2[b[i]]*13);break;}}}else{int sum = mp2[s]*13+mp1[s2];printf("%d\n",sum);}}}return 0;
}
【补充】
- 找到原因了,竟然是我的map写错了,把“jly”写成了"jul"这种错误下次不能再犯了。
提醒自己在每次写map的时候要有耐心,还要细心,写完检查一遍,确保没错,再继续后面的。 - scanf输入字符串的时候行末的\n会留下了,如果后面要用别的方式输入的话,要注意把这个\n去掉,可以用getchar
- fputs的用法要结合把末尾的\n换成\0的操作。
- 还有就是sscanf的用法
- 判断字符是否为数字可以用isdigit()函数,头,然后用atoi() 或者stoi()转成int型,前者参数为char*后者为string,头文件分别为stdlib和string。