HDOJ 1002 A + B Problem II 解题报告

今天研究 1002,,,搞得半死,虽说是一道简单的题目,真正做起来绝不是很容易的。。。

 

A + B Problem II

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 155352    Accepted Submission(s): 29405


Problem Description
I have a very simple problem for you. Given two integers A and B, your job is to calculate the Sum of A + B.
 

 

Input
The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line consists of two positive integers, A and B. Notice that the integers are very large, that means you should not process them by using 32-bit integer. You may assume the length of each integer will not exceed 1000.
 

 

Output
For each test case, you should output two lines. The first line is "Case #:", # means the number of the test case. The second line is the an equation "A + B = Sum", Sum means the result of A + B. Note there are some spaces int the equation. Output a blank line between two test cases.
 

 

Sample Input
2
1 2
112233445566778899 998877665544332211
 

 

Sample Output
Case 1:
1 + 2 = 3
 
Case 2:
112233445566778899 + 998877665544332211 = 1111111111111111110
 

 

Author
Ignatius.L
 

 解题思路:

这个是最简单的一道大数相加的题目吧。。

基本思路就是用两个字符数组来分别存放大数A,和大数B,

其次,做ACM的题目一定要注意的是输出格式,

非常严格,所以一定要小心。

包括中间的换行,

程序结束时不用换行。

空格等等。

 

看别人写的代码,有的用到指针,有的用到了memset

http://www.cnblogs.com/xiaolongchase/archive/2011/10/22/2221326.html

 

在这里,知道了strlen和sizeof的区别了。

strlen确实是用来确定字符实际长度的好办法。

http://www.cnblogs.com/carekee/articles/1630789.html

举例:
    eg1char arr[10] = "What?";
              int len_one = strlen(arr);
              int len_two = sizeof(arr);
              cout << len_one << " and " << len_two << endl;
    输出结果为:5 and 10
    点评:sizeof返回定义arr数组时,编译器为其分配的数组空间大小,不关心里面存了多少数据。strlen只关心存储的数据内容,不关心空间的大小和类型。

    eg2char * parr = new char[10];
              int len_one = strlen(parr);
              int len_two = sizeof(parr);
              int len_three = sizeof(*parr);
              cout << len_one << " and " << len_two << " and " << len_three << endl;
    输出结果:23 and 4 and 1
    点评:第一个输出结果23实际上每次运行可能不一样,

这取决于parr里面存了什么(从parr[0]开始知道遇到第一个NULL结束);

第二个结果实际上本意是想计算parr所指向的动态内存空间的大小,但是事与愿违,sizeof认为parr是个字符指针,

因此返回的是该指针所占的空间(指针的存储用的是长整型,所以为4;第三个结果,由于*parr所代表的是parr所指的地址空间存放的字符,所以长度为1

 下面是一个C++的代码:

 1 #include <iostream>
 2  using namespace std;
 3  void add(char a[],char b[])
 4  {
 5    char sum[1010]={' '};
 6    int flg=0;
 7    int temp =0;
 8    int len_a =strlen(a);
 9    int len_b =strlen(b);
10    int i=len_a;
11    int j=len_b;
12    for (;i>0;i--)
13    {
14      if (j>0)
15      {
16        temp =a[i-1]+b[j-1]+flg-96;    //写成temp=a[i-1]-'0'+b[i-1]-'0'+flg  会更好理解,这个语句是用来将temp对应的ascii码真正变为数字,从而用来确定是否进位。
17        j--;
18      }
19      else temp = a[i-1]+flg-48;
20      if (temp>=10)
21      {
22       flg=1;
23      }
24      else flg =0;
25      temp =temp%10;
26      sum[i]=temp+48;
27    }
28   if (flg==1)sum[0]=49;          //到这里前面的循环结束了,所以如果这时候flg为1的话,说明要进位,也就是最高位要再进一位。
29   i=0;
30   while (i<=len_a)
31   {
32     if (sum[i]!=' ')cout<<sum[i];    //在前面预留了一位,用来存放进位,如果没有进位的话,就不会输出。巧妙
33     i++;
34   }
35     cout<<endl;
36   }
37  void main()
38  {
39    int N;
40    while (cin >>N )
41    {
42      for (int i=1;i<=N;i++)
43      {
44        char a[1000];
45        char b[1000];
46        cin >>a;
47        cin >>b;
48        int len_a =strlen(a);
49        int len_b =strlen(b);
50        cout <<"Case "<<i<<":\n"<<a<<" + "<<b<<" = ";
51        if (len_a>=len_b)
52        {
53          add(a,b);
54        }
55        else add(b,a);
56        if (i!=N)cout<<endl;
57       }
58     }
59  }

 

 

 

折腾了好久,发现原来不是输出的问题。。。

 1 #include<stdio.h>
 2 #include<string.h>
 3 void add(char a[], char b[])
 4 {
 5     char c[1002]={' '};
 6     int len_a=strlen(a), len_b=strlen(b);
 7     int i=len_a;
 8     int j=len_b;
 9     int temp=0, flag=0;
10 
11         for( ; i>0 ; i--)
12         {
13             if(j>0)
14             {
15                 temp=a[i-1]-'0'+b[j -1]+flag-'0';
16                 j--;
17             }
18             else 
19                 temp=a[i-1]+flag-'0';
20             if(temp>=10)
21                 flag=1;
22             else 
23                 flag=0;
24             temp=temp%10;
25             c[i]=temp+'0';
26         }
27         
28     if(flag==1) c[0]='1';
29     for(i=0; i<=len_a; i++)
30     {
31         if(c[i]!=' ') printf("%c",c[i]);
32     }
33     printf("\n");
34 }
35 
36 int main()
37 {
38     char a[1001], b[1001];
39     int i, j, n;
40     int len_a, len_b;
41     scanf("%d", &n);
42     for(i=0;i<n;i++)
43     {
44         scanf("%s", &a);
45         len_a=strlen(a);
46         scanf("%s", &b);
47         len_b=strlen(b);
48         printf("Case %d:\n%s + %s = ", i+1, a, b);
49         if(len_a>=len_b)
50             add(a,b);
51         else
52             add(b,a);
53         if(i+1!=n)
54             printf("\n");
55 
56     }
57     return 0;
58 }

 

 1 #include <string>
 2 #include <iostream>
 3 using namespace std;
 4 void main ()
 5 {
 6     int n,i,j=1;
 7     char a[5000],b[5000],c[5000];
 8     scanf ("%d",&n);
 9     getchar ();
10     while (n--)
11     {
12         
13         for (i=0;i<5000;i++)
14             c[i]='0';
15         scanf ("%s%s",a,b);
16         strrev (a);
17         strrev (b);                          //倒转数组,使之对齐
18         for (i=0;a[i]!='\0'&&b[i]!='\0';i++)        //进行计算
19         {    if ((a[i]+b[i]+c[i]-96-48)<10)
20                 c[i]=a[i]+b[i]+c[i]-48-48;
21             else 
22             {
23                 c[i]=a[i]+b[i]+c[i]-48-58;      //减掉一个10
24                 c[i+1]=49;               //加上一个1
25             }
26         }
27         if (strlen(a)>strlen(b))               //看看两个数组哪个长度长,长的那个便是没有相加到最后一位的那个
28             for (;a[i]!='\0';i++)
29                 c[i]=a[i]+c[i]-48;
30         else if (strlen(a)<strlen(b)) 
31             for (;b[i]!='\0';i++)
32                 c[i]=b[i]+c[i]-48;
33         if (c[i]=='0')
34             c[i]='\0';
35         else c[i+1]='\0';
36         strrev (c);
37         strrev (a);
38         strrev (b);
39         if (n!=0)
40         cout<<"Case "<<j<<":"<<endl<<a<<" + "<<b<<" = "<<c<<endl<<endl;
41         else {cout<<"Case "<<j<<":"<<endl<<a<<" + "<<b<<" = "<<c<<endl;}
42         j++;          //控制 Case N;
43     }
44 }
45                         // strrev()  把字符串s的所有字符的顺序颠倒过来
46  

 

 

#include<iostream>
#include<string.h>
using namespace std;

#define MAX 1010
int add1[MAX], add2[MAX], res[MAX];
char tmp1[MAX], tmp2[MAX];
int main()
{
    int N, i, j, len, len1, len2, tmp, k;
        scanf("%d",&N);
        getchar();
        for(j=0;j<N;j++)
        {
            memset(add1,0,sizeof(add1));
            memset(add2,0,sizeof(add2));
            memset(res,0,sizeof(res));
            memset(tmp1,0,sizeof(tmp1));
            memset(tmp2,0,sizeof(tmp2));
            scanf("%s %s",tmp1,tmp2);
            len1 = strlen(tmp1);
            len2 = strlen(tmp2);
            for(i=len1-1,k=0;i>=0;i--)
                add1[k++] = tmp1[i] - '0';
                
            for(i=len2-1,k=0;i>=0;i--)
                add2[k++] = tmp2[i] - '0';
            tmp = 0;
            if(len1 >= len2)
            {
                for(i=0;i<=len1;i++)
                {
                    res[i] = (add1[i] + add2[i] +tmp)%10;
                    tmp = (add1[i] + add2[i] +tmp)/10;
                }
            }
            else if(len1 < len2)
            {
                for(i=0;i<=len2;i++)
                {
                    res[i] = (add1[i] + add2[i] +tmp)%10;
                    tmp = (add1[i] + add2[i] +tmp)/10;
                }
            }
            if(len1 >= len2) len = len1;
            else len = len2;
            printf("Case %d:\n%s + %s = ",j+1, tmp1 , tmp2);
            if(res[len]!=0) printf("%d",res[len]);    
            for(i=len-1;i>=0;i--)
                    printf("%d",res[i]);
        
            printf("\n");
            if(j!=N-1) printf("\n");
        }
    return 0;
}

 

转载于:https://www.cnblogs.com/Lee-geeker/archive/2013/04/27/3047930.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值