木有求助别人然后AC。。。。。
打完了上面这一行我都羞愧(*/ω\*)谁叫我是蒟蒻呢
先上我滴最终代码
1 #include<stdio.h>//高精度加法 2 #include<string.h> 3 4 char ar[1001],br[1001]; 5 int a,b; 6 7 void exchange() 8 { 9 char cr[1001];int c; 10 strcpy(cr,ar); 11 strcpy(ar,br); 12 strcpy(br,cr); 13 c=a;a=b;b=c; 14 } 15 16 void main() 17 { 18 int k; 19 scanf("%d",&k); 20 for (int j=1;j<=k;j++) 21 { 22 int i,n,t=0; 23 scanf("%s",ar); 24 scanf("%s",br); 25 a=strlen(ar); 26 b=strlen(br); 27 28 printf("Case %d:\n",j); 29 printf("%s + %s = ",ar,br); 30 31 if (a<b) exchange(); 32 33 for (i=1;i<=b;i++) 34 { 35 if (ar[a-i]+br[b-i]-2*‘0‘>9) 36 { 37 ar[a-i]=(ar[a-i]+br[b-i]-‘0‘)-10; 38 if (a-i>=1) ar[a-i-1]+=1; 39 else t=1; 40 } 41 else ar[a-i]=ar[a-i]+br[b-i]-‘0‘; 42 } 43 44 n=a-b-1; 45 while ((ar[n]>‘9‘)&&(n>0)) 46 { 47 ar[n]--; 48 ar[n-1]++; 49 } 50 51 if (ar[0]>‘9‘) 52 { 53 t=1; 54 ar[0]-=10; 55 } 56 57 58 if (t) printf("%d",t); 59 puts(ar); 60 if (j!=k) printf("\n"); 61 } 62 }
1002
开始大体写了个思路(虽然很简单(*/ω\*),但是真的用笔写了下来,这样以后不会被突如其来的思路
1 /* 2 把ar作为长数 3 把br加到ar上 4 加到最后一位考虑ar的进位问题 5 */
思路
进位问题考虑的还是比较周到==
但是中间出过一个错是 while()//我居然加了do,上百度知道问了一哈发现do不是C的关键字,真是不胜杯酌。。。。
提交了一次,不对,RUNTIME ERR,查了一下执行了错误命令,试验了几次发现gets和scanf的差别,顺便普及了string.h的几个函数
再提交,WA,找了AC过的代码比较一下输出结果,发现格式不对啊!关于格式真是改了无数次啊,Case *也就罢了,冒号还浪费了一次提交,再次不胜杯酌,对了这顺便看到有童鞋把数组开到1001,小细节注意。
再提交,还不对,这次应该就是结结实实的算法错误了,再往上看几行我又羞愧了(*/ω\*)。测试了几组数据,发现exchange函数未交换ar,br,ab也未交换。这个问题再改过来就没什么大问题了。中间补了一下集训的作业。到了大学也有寒假狂补作业的桥段你让我说什么好/(ㄒoㄒ)/~~
最后,让我们看一下别人家的代码/(ㄒoㄒ)/~~
1 #include <stdio.h> 2 3 #include <string.h> 4 5 int main() 6 { 7 int max(int a,int b); 8 void change(char str[],int num[]); 9 char str1[2][1001]; 10 int num1[1001]={0}; 11 int num2[1001]={0}; 12 int numsum[1001]={0}; 13 int lengthsum=0; 14 int count=0; 15 scanf("%d",&count); 16 for(int j=0;j<count;j++) 17 { 18 if(j) printf("\n"); 19 scanf("%s",str1[0]); 20 scanf("%s",str1[1]); 21 memset(num1,0,sizeof(num1)); 22 memset(num2,0,sizeof(num2)); 23 memset(numsum,0,sizeof(numsum)); 24 change(str1[0],num1); 25 change(str1[1],num2); 26 lengthsum=max(strlen(str1[0]),strlen(str1[1])); 27 int c = 0; 28 for(int i=0;i<lengthsum;i++) 29 { 30 numsum[i]=(num1[i]+num2[i]+c)%10; 31 c=(num1[i]+num2[i]+c)/10; 32 } 33 34 printf("Case %d:\n",j+1); 35 printf("%s + %s = ",str1[0],str1[1]); 36 if(c) printf("1"); 37 for(int i=lengthsum-1;i>=0;i--) 38 printf("%d",numsum[i]); 39 printf("\n"); 40 } 41 } 42 43 void change(char str[],int num[]) 44 { 45 int length=strlen(str); 46 int i=0; 47 for(i=0;i<length;i++) 48 num[length-i-1]=str[i]-‘0‘; 49 } 50 51 int max(int a,int b) 52 { 53 return a>b?a:b; 54 }
1
1 #include <iostream> 2 #include <string> 3 4 usingnamespace std; 5 6 string LSum ( string, string ); 7 8 int main() 9 { 10 string s_1, s_2; 11 int count_inside =0, count_outside; 12 cin >> count_outside ; 13 while ( count_inside != count_outside && cin >> s_1 >> s_2 ) 14 { 15 cout <<"Case "<<++count_inside <<":"<< endl; 16 cout << s_1 <<" + "<< s_2 <<" = "<< LSum ( s_1, s_2 ) << endl; 17 if ( count_inside != count_outside ) cout << endl; 18 } 19 return0; 20 } 21 22 string LSum ( string A, string B ) 23 { 24 string::size_type i = A.size(), j = B.size(); 25 int c =0; 26 string Ans; 27 while ( i || j ) 28 { 29 int tmp = c; 30 if ( i ) tmp += A[--i] -48; 31 if ( j ) tmp += B[--j] -48; 32 if ( ( i +1 ) || ( j +1 ) ) 33 Ans += ( tmp %10+48 ); 34 c = tmp /10; 35 } 36 if ( c ) Ans += c +48; 37 string AnsCopy ( Ans ); 38 string::size_type AnsLength = Ans.size(); 39 for ( int k = AnsLength; k !=0; --k ) 40 Ans[AnsLength-k] = AnsCopy[k-1]; 41 return Ans; 42 }
2
1 #include <iostream> 2 #include <string.h> 3 using namespace std; 4 void add ( char a[], char b[] ) 5 { 6 char sum[1010] = {‘ ‘}; 7 int flg = 0; 8 int temp = 0; 9 int len_a = strlen ( a ); 10 int len_b = strlen ( b ); 11 int i = len_a; 12 int j = len_b; 13 for ( ; i > 0; i-- ) 14 { 15 if ( j > 0 ) 16 { 17 temp = a[i-1] + b[j-1] + flg - 96; 18 j--; 19 } 20 else temp = a[i-1] + flg - 48; 21 if ( temp >= 10 ) 22 { 23 flg = 1; 24 } 25 else flg = 0; 26 temp = temp % 10; 27 sum[i] = temp + 48; 28 } 29 if ( flg == 1 ) sum[0] = 49; 30 i = 0; 31 while ( i <= len_a ) 32 { 33 if ( sum[i] != ‘ ‘ ) cout << sum[i]; 34 i++; 35 } 36 cout << endl; 37 } 38 int main() 39 { 40 int N; 41 while ( cin >> N ) 42 { 43 for ( int i = 1; i <= N; i++ ) 44 { 45 char a[1000]; 46 char b[1000]; 47 cin >> a; 48 cin >> b; 49 int len_a = strlen ( a ); 50 int len_b = strlen ( b ); 51 cout << "Case " << i << ":\n" << a << " + " << b << " = "; 52 if ( len_a >= len_b ) 53 { 54 add ( a, b ); 55 } 56 else add ( b, a ); 57 if ( i != N ) cout << endl; 58 } 59 } 60 return 0; 61 }
3
代码1开了一个新数组,最神奇的地方在于,倒序存储!!!读入字符串之后将其倒序转为整形数组,然后整形数组倒序相加,另外还开一个c存进位(c可省略,直接加到求和数组上)比我翻来覆去折腾ar方便多了,而且进位问题简单多了(我当时为啥不开新数组来着?啊,貌似是因为长整数多出来的那部分的进位问题,但是倒着存很简单的解决了这个问题。)
代码3也是c++的,不过勉强能看懂(可读性的重要性啊)思路和我的大同小异,基本上就是一样啊
代码2是c++的看起来真费劲,大体看懂了,和代码3与我的差别不大,主要区别是对下标的逻辑判断
我的代码、代码23为了处理可能多出来的最高位和长整数多出来的位数都多加了一个变量以及判断导致算法的繁琐,代码1倒序存储很惊艳的解决了这个问题。其实,这道题的关键在于进位的问题,而多余部分的进位问题的处理方式决定了算法的核心区别。
总结:
1.while ()
2.gets&scanf//gets一读读一行,空格也读进去,scanf就不会
3.string.h
4.不要因为格式而浪费提交!!!
写这样一篇总结还真麻烦啊/(ㄒoㄒ)/~~