ZOJ_1205_Martian Addition

Martian Addition

Time Limit: 2 Seconds       Memory Limit: 65536 KB

  In the 22nd Century, scientists have discovered intelligent residents live on the Mars. Martians are very fond of mathematics. Every year, they would hold an Arithmetic Contest on Mars (ACM). The task of the contest is to calculate the sum of two 100-digit numbers, and the winner is the one who uses least time. This year they also invite people on Earth to join the contest.
  As the only delegate of Earth, you're sent to Mars to demonstrate the power of mankind. Fortunately you have taken your laptop computer with you which can help you do the job quickly. Now the remaining problem is only to write a short program to calculate the sum of 2 given numbers. However, before you begin to program, you remember that the Martians use a 20-based number system as they usually have 20 fingers. 

Input:
You're given several pairs of Martian numbers, each number on a line. 
Martian number consists of digits from 0 to 9, and lower case letters from a to j (lower case letters starting from a to present 10, 11, ..., 19). 
The length of the given number is never greater than 100.

Output:
For each pair of numbers, write the sum of the 2 numbers in a single line.

Sample Input:
1234567890
abcdefghij
99999jjjjj
9999900001

Sample Output:
bdfi02467j
iiiij00000
 
题意和思路:题目意思很容易读懂,有点类似大数相加的感觉。我做了很久,用的方法也很繁琐,不过看了别人的解题报告发现总体思路也是类似,主要就是先都放入字符数组,然后处理的时候从尾部(最低位)开始处理,要将字符转化为数字来计算,自己控制进位。相信这个很多人能想到思路,但是实现起来确实很麻烦,我说几个易错点吧。
 
1.数组不要只设置101,有种进位方式容易遗漏j+j=1i 结果别两个相加的数多1位
2.注意001+2=3不等于003所以要忽略前面的0
 
Sample Program Here
/******************************************
**
**      Author: Wan KaiMing
**      Date:   2012-10-30-18.38 星期二
**
*******************************************/


#include<iostream>
#include<cstring>
using namespace std;


int main(){
   char a[200],b[200];//相加的两个数
   memset(a,'x',sizeof(a));
   memset(b,'x',sizeof(b));
   while(cin>>a>>b){
	      //初始化全为-1 这样之后可以用来确定长度

      //先将a,b数据倒置下,这样a[0]就是最低位了
      int i=0;
      //先得到a b的长度
      int len_a=0,len_b=0;
      while(a[i++]!='x') len_a++;
      len_a--; //去除多算的\0

      i=0;
      while(b[i++]!='x') len_b++;
      len_b--;


      char t; //用于暂存数据

      //进行元素的交换完成倒置
      for(i=0;i<len_a/2;i++){
          t=a[len_a-i-1];
          a[len_a-i-1]=a[i];
          a[i]=t;
      }

      for(i=0;i<len_b/2;i++){
          t=b[len_b-i-1];
          b[len_b-i-1]=b[i];
          b[i]=t;
      }

      //进行相加的操作
      char sum[101]; //用于保存和
      char add='0'; //保存进位的值
      memset(sum,'x',sizeof(sum));
      int len;
      len=len_a>len_b?len_a:len_b; //取长度大的

      //完成加法操作
      for(i=0;i<len;i++){

        if(a[i]=='x'||a[i]==0) a[i]='0';  //不要忘记是字符串最后会多个0
        if(b[i]=='x'||b[i]==0) b[i]='0';
        if(a[i]>='a'&&a[i]<='j')  a[i]=a[i]-'a'+10;
		else a[i]=a[i]-'0';
        if(b[i]>='a'&&b[i]<='j')  b[i]=b[i]-'a'+10;
		else b[i]=b[i]-'0';
        //转化成整数计算
        int one,two,add2; //add2是进位
        one=a[i];
        two=b[i];
        add2=add-'0';
        add=(one+two+add2)/20+'0';
		if(add!='0'&&i==len-1) len++;  //如果最高位进位了 那么长度增加1位不要忘记这种情况
        if((one+two+add2)%20>=10){
		     sum[i]=(one+two+add2)%20-10+'a';
		}
        else sum[i]=(one+two+add2)%20+'0';

      }



	  //输出前先略去开头的0
	  for(i=len-1;i>=0;i--){
		  if(sum[i]!='0'){
		     len=i+1;//即len-1=i
			 break;
		  }
	  }

      //输出加法的结果,因为倒置过了记得从最后开始输出
      for(i=len-1;i>=0;i--){
         cout<<sum[i];
      }
      cout<<endl;
	  memset(a,'x',sizeof(a));
      memset(b,'x',sizeof(b));

   }
   return 0;
}


 
///由于我觉得自己算法太过繁琐,特地奉上转载来的一个解法,思路基本相同,但是代码比我更加清晰,简约
转载自:http://www.cnblogs.com/hoodlum1980/archive/2009/01/10/1373130.html
 
Sample Program Here
/* ZOJ - 1205 , 20进制数想加 */
#include <stdio.h>
#include <string.h>

char* NUMS="0123456789abcdefghij";

/*分别是读取的输入行,加数a,b,计算结果c */
char line[105],a[105],b[105],c[105];

/*字符换算为实际数值,例如'a'->10,'b'->11*/
int CharToVal(char c)
{
    return strchr(NUMS, c)-NUMS;
}

/*解析输入*/
void CopyNum(char* dest, const char* line)
{
    int i,len=strlen(line);
    for(i=0;i<len;i++)
    {
        dest[i]=CharToVal(line[len-1-i]);
    }
}

/*打印加法结果,注意结尾如果为0也要打印0*/
void PrintResult()
{
    int i=101;
    while(c[i]==0) i--;
    
    if(i<0) i=0;        /*非常重要,可以保证至少要打印一个0。*/
    
    for(;i>=0;i--)
    {
        printf("%c", NUMS[c[i]]);
    }
    printf("\n");
}

/*做加法: c=a+b; */
void Add()
{
    int i;
    int k=0,sum;/*进位的数值*/
    for(i=0;i<102;i++)
    {
        sum = a[i] + b[i] + k;
        c[i] = sum%20;
        k = sum/20;
    }
}

int main()
{
    while(scanf("%s",line)!=EOF && strcmp(line,"END")!=0)
    {
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));
        CopyNum(a,line);            /*获取加数A*/
        scanf("%s",line);
        CopyNum(b,line);            /*获取加数B*/
        Add();                                /*C=A+B;*/
        PrintResult();                /*打印出结果*/
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值