1044 火星数字 (20 分)
题目链接
算法分析
1.用两个字符串数组存下每一个数字对应的三个字母。
2.进入循环后,首先对读入的类型进行判断,并用flag存下,最终用于输出结果。
3.然后分两种情况进行分析和处理:
(1)对于输入的数字,将其转化为十进制数,然后再转化为十三进制数。
(2)对于输入的字母,每三位进行计算,转化为十进制数。
测试点的问题
测试点一
其实就是对输入0时的特殊判断,这里我尽量说的详细一些。
我的算法中用ans数组存下了结果的每一位,输出时对照字符串数组输出。
由于我采用的是每次循环通过t(栈顶)的改变来覆盖和修改ans数组的元素。
所以在处理0的时候,由于t不能发生改变,因此就把上次处理的结果输出了,出了问题。
但是,它之所以难以被发现,是因为只有一组数据,输入0时,答案是正确的。
所以,以后一定要注意这种类型的错误:算法中用到手写栈的覆盖,要考虑临界情况。
代码实现
#include<bits/stdc++.h>
using namespace std;
#define N 15
int t, sum;
const char *earth[N] = {"tret", "jan", "feb", "mar", "apr", "may", "jun", "jly", "aug", "sep", "oct", "nov", "dec"};
const char *mars[N] = {"tret", "tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou"};
char com[N];
int ans[N];
int flag;
int judge(){
for(int i = 0; i < 13; ++ i){
if(!strcmp(com, earth[i]))//strcmp的使用:两个字符串若相等返回0
return i;//低位
else if(!strcmp(com, mars[i]))
return i * 13;//高位
}
return 0;
}
int main(){
int n;
char s;
scanf("%d", &n);
s = getchar();//吞下n后面的空格
for(int i = 1; i <= n; ++ i){
t = 0;
sum = 0;
flag = 0;
while((s = getchar()) != '\n'){
if(isdigit(s)){
flag = 1;
sum = sum * 10 + (s - '0');
}
else if(s == ' ')//比较重要的处理
continue;
else{
com[t ++] = s;
if(t == 3){
sum += judge();
t = 0;
}
}
}
if(flag == 1){//第一种情况的输出
int tel = 0;
if(!sum) ans[++ tel] = 0;
while(sum){
ans[++ tel] = sum % 13;
sum /= 13;
}
if(tel == 1)
printf("%s", earth[ans[1]]);
else{
printf("%s", mars[ans[2]]);
if(ans[1]) printf(" %s", earth[ans[1]]);//高位不为0,低位为0则不输出
}
printf("\n");
}
else{//第二种情况的输出
printf("%d\n", sum);
}
}
return 0;
}