目录
1002:写出这个数
读入一个正整数 n,计算其各位数字之和,用汉语拼音写出和的每一位数字。
输入格式:
每个测试输入包含 1 个测试用例,即给出自然数 n 的值。这里保证 n 小于 10100。
输出格式:
在一行内输出 n 的各位数字之和的每一位,拼音数字间有 1 空格,但一行中最后一个拼音数字后没有空格。
输入样例:
1234567890987654321123456789
输出样例:
yi san wu
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
思路:
1.求和
我们做这道题的第一步,就是要求出输入的字符串中数字你字符的和,那这怎么求呢?
很好办,我们初始定义一个int类型变量sum,依次遍历字符串数组,将当前字符加到sum里面,但是这个字符是char类型的,就算系统默认转化成了int类型,也是ASCII码格式的,完全不是之前的那个数字字符.
我们知道,ASCII中,数字字符0,1,2......的ASCII码是相差为1的,也就是说,这些数字字符的ASCII码-'0'的ASCII码就可以等于正确的数字字符,和我们之前讲的求字母序号一样,减去'A'.
这样我们求到了字符串的数字字符和sum.
1.2代码:
char a[101];//字符串
cin>>a; //输入这个字符串
int sum=0; //字符串a的数字字符和
int t=strlen(a); //求字符串a的长度
for(int i=0;i<t;i++) //遍历a字符串
sum+=a[i]-'0'; //求字符串a的和
2.找到sum的每一位
我们可以写一个函数来解决:
我们首先先求出sum是一个几位的数字:
不断的while循环,知道r等于0为止(r在最开始赋值为sum),期间将r/=10(将r除以10),然后将计数器t不断的++.
这样,t就是sum的数字长度了.
接下来我们就可以用一个数组nums来存sum的每一位了,怎么存呢?
我们知道sum的位数了,就可以用一个函数来求sum的当前位置的数是多少:
首先,函数参数是t和n,t默认为10,n就代表sum的位数,如果n为1位的话,那么当前位最小是1,就返回1,如果n为2位的话,就返回10,在n以上的话,利用while循环,判断返回多少,就是求t的n-1次方是多少,将其返回.
返回之后呢?我们的nums数组,就可以进行存储,我们存储什么呢?难道存储函数里面返回的10的n-1次方吗?
我们知道,求sum的每一位,我们需要再次除以这个函数的返回值,比如说sum是135,长度为3,用函数运算,返回值是10^(3-1)=100,将135/100=1,就是sum的第一位,之后将sum赋值为sum除以函数返回值的余数,在这里,sum=sum%100=35;然后循环处理,目前长度为2,返回值是10,35/10=3,是sum的第二位,这样依次下去,直到长度为0为止.
经过这样的操作,nums里面存的就是sum正序数字的每一位了.
2.2代码:
int check(int t,int n){ //求t的n-1次方
int r=t;
if(n==1) //长度为1
return 1; //就返回1
else if(n==2) //长度为2
return t; //返回10
else if(n>2){ //如果长度大于了2
while(n>2){ //不断*10
r*=t; //*10
n--; //长度减1
}
}
return r;//返回t的n-1次方
}
int get(int t,int nums[]){ //求t的长度
int tl=0,t1=t; //tl是sum的长度,t1赋值为t
while(t1>0){ //找t的长度
t1/=10; //不断的除以10
tl++; //长度++
}
for(int i=0;i<tl;i++){ //求出t的每一位数字到nums里面
nums[i]=t/check(10,tl-i); //赋值
t=t%check(10,tl-i); //除余
}
return tl; //返回长度
}
3.汉语拼音输出数字
计算完了sum的各位数字,我们需要按照题目要求汉语拼音输出了!
可以写一个函数,参数为一个int类型的整数:
如果为0,输出....
如果为1,输出....
......
如果为9,输出"jiu";
这样遍历nums的时候,带入这个函数,就可以汉语拼音输出了!
因为题目说了行末不能有多余的空格,所以我们需要特判一下!
3.2代码:
void pd(int c,int j,int i){ //汉语拼音输出数字
if(c==1)
cout<<"yi";
else if(c==2)
cout<<"er";
else if(c==3)
cout<<"san";
else if(c==4)
cout<<"si";
else if(c==5)
cout<<"wu";
else if(c==6)
cout<<"liu";
else if(c==7)
cout<<"qi";
else if(c==8)
cout<<"ba";
else if(c==9)
cout<<"jiu";
else if(c==0)
cout<<"ling";
if(j!=i) //行末不能有多余空格的特判
cout<<" ";
}
完整代码:
#include<bits/stdc++.h>
using namespace std;
int check(int t,int n){ //求t的n-1次方
int r=t;
if(n==1) //长度为1
return 1; //就返回1
else if(n==2) //长度为2
return t; //返回10
else if(n>2){ //如果长度大于了2
while(n>2){ //不断*10
r*=t; //*10
n--; //长度减1
}
}
return r;//返回t的n-1次方
}
int get(int t,int nums[]){ //求t的长度
int tl=0,t1=t; //tl是sum的长度,t1赋值为t
while(t1>0){ //找t的长度
t1/=10; //不断的除以10
tl++; //长度++
}
for(int i=0;i<tl;i++){ //求出t的每一位数字到nums里面
nums[i]=t/check(10,tl-i); //赋值
t=t%check(10,tl-i); //除余
}
return tl; //返回长度
}
void pd(int c,int j,int i){ //汉语拼音输出数字
if(c==1)
cout<<"yi";
else if(c==2)
cout<<"er";
else if(c==3)
cout<<"san";
else if(c==4)
cout<<"si";
else if(c==5)
cout<<"wu";
else if(c==6)
cout<<"liu";
else if(c==7)
cout<<"qi";
else if(c==8)
cout<<"ba";
else if(c==9)
cout<<"jiu";
else if(c==0)
cout<<"ling";
if(j!=i) //行末不能有多余空格的特判
cout<<" ";
}
int main(){
char a[101];//字符串
cin>>a; //输入这个字符串
int sum=0; //字符串a的数字字符和
int t=strlen(a); //求字符串a的长度
for(int i=0;i<t;i++) //遍历a字符串
sum+=a[i]-'0'; //求字符串a的和
int s[10]; //s为sum的每一位数字
int i=0;
i=get(sum,s)-1; //求出sum的长度
for(int j=0;j<=i;j++) //遍历
pd(s[j],j,i); //输出
cout<<endl;
return 0;
}
时间复杂度:
说了n最多是10^100次方,那么说明n最多是100位,get函数的复杂度就是O(100);
最后遍历输出的时间复杂度也是O(100),两者相加就是O(200),算是非常非常快的了!
总结:
这道题考了学生们关于字符串处理,字符串转整数,整数求长度,求整数的每一位的应用,总的来说还是比较难的!