【1002】高精度加法,此处应有掌声~(*/ω\*)

木有求助别人然后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ㄒ)/~~

时间: 2024-12-26 09:25:47

【1002】高精度加法,此处应有掌声~(*/ω\*)的相关文章

问题 B: 【高精度】简单高精度加法

问题 B: [高精度]简单高精度加法 时间限制: 1 Sec  内存限制: 64 MB提交: 94  解决: 27[提交][状态][讨论版] 题目描述 修罗王解决了计算机的内存限制问题,终于可以使用电脑进行大型的魔法运算了,他交给邪狼的第一个任务是计算两个非负整数A.B的和,其中A和B的位数在5000位以内. 输入 共两行数据,第一行为一个非负整数A,第二行为一个非负整数B,A.B的位数均在5000以内. 输出 输出一个非负数,即两数之和. 样例输入 1111111111 2222222222

C语言(7)--高精度加法、减法、乘法、今天是星期几、四位平方数、候选人选票问题

1.高精度加法.减法.乘法 #include <stdio.h> #include <string.h> #include <malloc.h> void plus(char *a,char *b,char *c);//自定义高精度加法函数 void sub(char *a,char *b,char *c);//自定义高精度减法函数 void multiply(char *a,char *b,char *c);//自定义高精度乘法函数 int main() { char

中石油-【高精度】简单高精度加法

问题 B: [高精度]简单高精度加法 时间限制: 1 Sec  内存限制: 64 MB提交: 63  解决: 20[提交][状态][讨论版] 题目描述 修罗王解决了计算机的内存限制问题,终于可以使用电脑进行大型的魔法运算了,他交给邪狼的第一个任务是计算两个非负整数A.B的和,其中A和B的位数在5000位以内. 输入 共两行数据,第一行为一个非负整数A,第二行为一个非负整数B,A.B的位数均在5000以内. 输出 输出一个非负数,即两数之和. 样例输入 1111111111 2222222222

leetcode 66. Plus One(高精度加法)

Given a non-negative number represented as an array of digits, plus one to the number. The digits are stored such that the most significant digit is at the head of the list. 题解:简单的高精度加法,要注意[9]这种输入,要多一位. class Solution { public: vector<int> plusOne(v

A1087. 高精度加法

体验一下,高精度的算法 /* * ===================================================================================== * * Filename: a1087.c * * Description: Rainboy_RT * * Version: 1.0 * Created: 2014-07-04 14:54:08 * Revision: none * Compiler: gcc * * Author: Rain

用c++实现高精度加法

c++实习高精度加法 最近遇到一个c++实现高精度加法的问题,高精度问题往往十复杂但发现其中的规律后发现并没有那么复杂,这里我实现了一个整数的高精度加法,主要需要注意以下几点: 1:将所需输入的数据以字符数组的形式输入,建立字符数组,建立相应的整数数组,然后一一映射,以此来实现数据的输入,需要注意的是,当实现字符向数字映射时,应该减去相应的ASCII偏移值,即48. 2:为了模拟我们在纸上手算的进位模拟运算,我们将字符数组反向填入整数数组,上图的后几行代码实现了这个操作. 3:实现进位加法,这是

POJ 3181 Dollar Dayz(完全背包+简单高精度加法)

POJ 3181 Dollar Dayz(完全背包+简单高精度加法) http://poj.org/problem?id=3181 题意: 给你K种硬币,每种硬币分别是1美元,2美元-K美元且可以无限使用,问你用上面K种硬币构成n美元的话有多少种方法? 分析: 本题是一道明显的完全背包问题, 不过本题还可以换一种方法来看: 整数n由前K个自然数构造, 一共有多少种方法? (虽然本题要用到高精度加法, 但是很简单, 不要被吓到哦) 首先是DP部分: 令dp[i][j]==x 表示由前i种硬币构成j

leetcode 67. Add Binary (高精度加法)

Given two binary strings, return their sum (also a binary string). For example,a = "11"b = "1"Return "100". 简单的二进制高精度加法. class Solution { public: string addBinary(string a, string b) { string ans=""; int c=0,i=a.len

[BASIC-29] 高精度加法

基础练习 高精度加法 时间限制:1.0s   内存限制:512.0MB 问题描述 输入两个整数a和b,输出这两个整数的和.a和b都不超过100位. 算法描述 由于a和b都比较大,所以不能直接使用语言中的标准数据类型来存储.对于这种问题,一般使用数组来处理. 定义一个数组A,A[0]用于存储a的个位,A[1]用于存储a的十位,依此类推.同样可以用一个数组B来存储b. 计算c = a + b的时候,首先将A[0]与B[0]相加,如果有进位产生,则把进位(即和的十位数)存入r,把和的个位数存入C[0]