就是我们平常说的数字黑洞问题。判断一个数字是不是回文数,如果是,输出,不是,则翻转相加继续判断。
题很简单,体现我是一个智障的本质。
我直接就随便设了两个字符串a和b各十五位,寻思怎么也够了,然后就字符串判断,翻转,atoi转int,再sprintf转字符串。
没看见人家说的最大输入不超过1000位。
我用atoi溢出,换atol,再换atoll,简直逗比,你就算是long long,那也禁不住1000位的输入啊。因此要使用字符串的加法。
先把我自己的分析一下吧。还是有一点教训的。主要是几个点浪费了时间。
先看我的思路,虽然蠢但是除了最后一个测试点都可以过的。
接收字符数组并判断。翻转。转int。相加。判断。继续下去。
首先是翻转函数,如下:
void reverseL(char* a,char* b)
{
int l=strlen(a);
for(int i=0;i
注意这里的char* a,在调用时要事先声明为char a[50]之类,否则会报段错误。因为只声明char*a就调用,因为未分配空间会溢出。这样做不好,推荐使用reverse函数直接翻转。但是reverse翻转会破坏原来的变量,是在它之上直接反转,这样不符合我们的要求。因此可以给他套上一层壳子,如下:
string rev(string s) {
reverse(s.begin(), s.end());
return s;
}
利用值传递不改变原来的变量,从而返回另一个string。这种用法要记住,关键在于参数是string,返回值也会string。
判断函数如下:
int judgeL(char* a)
{
int l=strlen(a);
//if(l==1&&a[0]==0)
//return 1;
for(int i=0;i
也很蠢,本来直接反转然后看他们俩是否相等即可。
在这里我们明确两点,其一,想对字符串操作,形参的类型必须是char*,实参必须是char* a[100]之类,其二,在函数中改变字符串中的值那就是真的改变了。因为传进去的本质上是字符串的首地址,是直接按地址改的。与传string不同。
然后判断即可,如下:
int num=0;
int flag=judgeL(n1);
while(flag==0&&num<10)
{
reverseL(n1,n2);
printf("%s + %s =",n1,n2);
long long int a=atoll(n1);
long long int b=atoll(n2);
long long int c=a+b;
//_itoa(c,n1,10);
//sprintf(n1,"%d",a);
//sprintf(n2,"%d",b);
sprintf(n1,"%lld",c);
printf(" %s\n",n1);
num++;
flag=judgeL(n1);
}
注意itoa函数是不能使用的,但可以使用sprintf函数,重新复习一下sprintf函数,三个参数,第一个是结果b,第二个是要转换的变量a的解释方式,第三个是要转换的变量a。如上我们要把int的a转换成char*的b,那么三个变量依次是b,"%d",a,注意第二个不是"%s",这个容易记混。
这样在数字较小时是正确的。下面我们看AC代码。
翻转函数在上文我们已经分析过了。现在我们分析核心函数,string加法,如下:
string add(string s1,string s2)
{
string s=s1;
int len=s1.size();
int carry=0;
for(int i=len-1;i>=0;i--)
{
s[i]=(s1[i]-'0'+s2[i]-'0'+carry)%10+'0';
carry=(s1[i]-'0'+s2[i]-'0'+carry)/10;
}
if(carry==1)
s="1"+s;
return s;
}
参数两个string,返回值亦为string。首先注意一点,要在函数中声明一个string作为和,设其为s,一定要给s初始化,这里使s=s1,不初始化会报错。然后初始化进位为0。从string的最后一位开始一直加到第一位,先求每位的和,然后求此位的进位。如果全算完了进位还是1,那么在最前面加一个1。
对于string来说,在最前面加一个1可以直接写为s=“1”+s;很方便。然后return s即可。之后判断并输出。
本题我们要学会两种常用函数的写法:
字符串加法以及字符串翻转。
PS:代码如下:
#include
#include
#include
#include