A+B Problem IV

时间限制:1000 ms  |  内存限制:65535 KB
难度:3
 
描述
acmj最近发现在使用计算器计算高精度的大数加法时很不方便,于是他想着能不能写个程序把这个问题给解决了。
 
输入
包含多组测试数据
每组数据包含两个正数A,B(可能为小数且位数不大于400)
输出
每组输出数据占一行,输出A+B的结果,结果需要是最简的形式。
样例输入
1.9 0.1
0.1 0.9
1.23 2.1
3 4.0
样例输出2
1
3.33
7

测试数据都对,又在网上找了别人说的有坑的侧试数据,也对,就是提交不上有兴趣的看下,,欢迎知道原因的指导一:

#include <iostream>
using namespace std;

bool flag;//标记是否小数部分向整数部分有进位

//计算整数部分的加法
string add_Int(string s1,string s2)
{
  if(s1.length()<s2.length())
  {
    string t=s1;
    s1=s2;
    s2=t;
  }
for(int i=s1.length()-1,j=s2.length()-1;i>=0;i--,j--)
{
  s1[i]=char(s1[i]+(j>=0?s2[j]-'0':0));

  if(s1[i]-'0'>=10)
  {
    s1[i]=char((s1[i]-'0')%10+'0');
    if(i)
      s1[i-1]++;
  else
    s1="1"+s1;
  }
}
  return s1;
}
//计算小数部分的加法
string add_Dec(string s1,string s2)
{
  //如果小数的位数不相同
  if(s1.length()!=s2.length())
  {
    if(s1.length()<s2.length())
    {
      string t=s1;
      s1=s2;
      s2=t;
    }
for(int i=s2.length()-1,j=s2.length()-1;i>=0;i--,j--)
{
   s1[i]=char(s1[i]+(j>=0?s2[j]-'0':0));

   if(s1[i]-'0'>=10)
  {
    s1[i]=char((s1[i]-'0')%10+'0');
    if(i)
      s1[i-1]++;
    else
      flag=true;
   }
  }
}
//小数部分位数同
if(s1.length()==s2.length())
{
  for(int i=s1.length()-1,j=s2.length()-1;i>=0;i--,j--)
  {
    s1[i]=char(s1[i]+(j>=0?s2[j]-'0':0));

    if(s1[i]-'0'>=10)
    {
      s1[i]=char((s1[i]-'0')%10+'0');
      if(i)
        s1[i-1]++;
      else
        flag=true;
    }

  bool flag1=true;

  for(int i=s1.length()-1;i>=0;--i)
    if(s1[i]!='0')
    {
      flag1=false;
      break;
    }
  if(flag1)
  {
    s1.clear();
  s1+="0";
  }

  }
}
  return s1;
}

int main()
{
  string s1,s2;
  while(cin>>s1>>s2)
  {
    string s1_Int,s1_Dec,s2_Int,s2_Dec;
    //s1的整数部分,s1的小数部分 ,s2的整数部分,s2的小数部分

    int s1_find=s1.find('.');//找到小数点的位置,把整数和小数分开来计算
    if(s1_find!=-1)//如果存在小数点
    {
      for(int i=0;i<s1.find('.');++i)
      s1_Int+=s1[i];
      for(int i=s1.find('.')+1;i<s1.length();++i)
      s1_Dec+=s1[i];
    }
    if(s1_find==-1)//如果不存在小数点
    {
      s1_Int+=s1;
      s1_Dec+="0";
    }

 int s2_find=s2.find('.');//s2的小数点的位置
  if(s2_find!=-1)//如果存在小数点
  {
    for(int i=0;i<s2.find('.');++i)
    s2_Int+=s2[i];
    for(int i=s2.find('.')+1;i<s2.length();++i)
    s2_Dec+=s2[i];
  }
 if(s2_find==-1)//如果不存在小数点
  {
    s2_Int+=s2;
    s2_Dec+="0";
  }

    flag=false;//默认为false如果有小数部分进位,则值为true
    string t_Dec=add_Dec(s1_Dec,s2_Dec);//先做小数部分的加法

    string t_Int_Carry;//小数加法时向正数有进位
    string t_Int;//小数加法向正数没有进位

    if(flag)// 如果小数部分向整数部分有进位
    t_Int_Carry=add_Int(add_Int(s1_Int,s2_Int),"1");
    else//小数部分向整数部分没有进位
    t_Int=add_Int(s1_Int,s2_Int);

  if(t_Dec=="0")//如果小数部分为零
    if(flag)//小数部通过向整数部分进位 产生的0
      cout<<t_Int_Carry<<endl;
    else//两个数本来都为整数
       cout<<t_Int<<endl;
  else//小数部分不为零     

  {
    if(flag)
      cout<<t_Int_Carry<<"."<<t_Dec<<endl;
    else
      cout<<t_Int<<"."<<t_Dec<<endl;
   }

  }
  return 0;
}

二:

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

string align(string ,int ,int );

int main()
{
int i,j,k;
string a,b;
while(cin>>a>>b)
{
for(j=0;j<a.length() && a[j]!='.';j++);
k=a.length() -j;
for(i=0;i<b.length() && b[i]!='.';i++);

if(i>j)
j=i;
if(b.length() -i>k)
k=b.length() -i; //分别得到整数最大位数j和小数最大位数k

a=align(a,j,k);
b=align(b,j,k); //按位对齐

for(i=a.length ()-1,j=0;i>=0;i--)
{
if(a[i]!='.')
{//加法运算
a[i]=a[i]+b[i]+j-'0';
j=0;
if(a[i]>'9')
{
j=1;
a[i]-=10;
}
}
}
if(j)
a='1'+a; //补进位

for(i=0;a[i]=='0';i++); //消前导0
for(b="",j=a.length ()-1;a[j]=='0';j--); //消尾数0

if(a[j]=='.')
j--; //整数处理
for(;i<=j;i++)
b+=a[i];
cout<<b<<endl;
}
return 0;
}

string align(string s,int ni,int nf)
{//数据位对齐
int i,j,k;
for(j=0;j<s.length()&&s[j]!='.';j++);

if(j==s.length())
s+=".0";
k=s.length()-j;

for(i=0;i<ni-j;i++)
s='0'+s;
for(i=0;i<nf-k;i++)
s+='0';
return s;
}

下面附上在网上看的别人的代码。。。

#include<stdio.h>
#include<string.h>
char s1[410],s2[410];
int a1[820],b1[820];
char result[820];
void create(char *s,int *a)
{
int len=strlen(s);
int k;
if(strchr(s,'.')!=NULL) //判断有无小数点
k=strchr(s,'.')-s; //标记小数点的位置
else
k=len; // 无小数点
for(int i=k+1,j=399;i<len;i++,j--)//小数点后面的存到前四百位
a[j]=s[i]-'0';
for(int i=k-1,j=400;i>=0;i--,j++)//小数点前面的存放到后四百位
a[j]=s[i]-'0';
}
void init()
{
memset(a1,0,sizeof(a1));
memset(b1,0,sizeof(b1));
memset(result,0,sizeof(result));
}
void sum()
{
int s,v=0;
for(int i=0;i<820;i++)
{
s=a1[i]+b1[i]+v;
result[i]=s%10;
v=s/10;
}
}
void print()
{
int i=820;
while(result[i]==0&&i>=400)
{
i--;
}
int j=0;
while(result[j]==0&&j<400)
{
j++;
}
if(i==399&&j==400)//全是零的情况
printf("0\n");
else
{
for(;i>=400;i--)
{
printf("%d",result[i]);
}
if(j!=400)
{
printf(".");
}
for(int i=399;i>=j;i--)
printf("%d",result[i]);
printf("\n");
}
}
int main()
{
while(~scanf("%s %s",s1,s2))
{
init(); //每计算一次初始化数组
create(s1,a1);//转化过程(2倍数组倒序存放小数或整数)
create(s2,b1);//转化过程
sum();//进位求和过程
print();
}
return 0;
}

nyoj A+B Problem IV的更多相关文章

  1. nyoj 513-A+B Problem IV (java BigDecimal, stripTrailingZeros, toPlainString)

    513-A+B Problem IV 内存限制:64MB 时间限制:1000ms 特判: No 通过数:1 提交数:2 难度:3 题目描述: acmj最近发现在使用计算器计算高精度的大数加法时很不方便 ...

  2. NYOJ--513--A+B Problem IV(大数)

    A+B Problem IV 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 acmj最近发现在使用计算器计算高精度的大数加法时很不方便,于是他想着能不能写个程序把这 ...

  3. NYOJ 219 An problem about date

    An problem about date 时间限制:2000 ms  |  内存限制:65535 KB 难度:2   描述 acm的iphxer经常忘记某天是星期几,但是他记那天的具体日期,他希望你 ...

  4. nyoj 803-A/B Problem

    803-A/B Problem 内存限制:64MB 时间限制:1000ms 特判: No 通过数:2 提交数:4 难度:3 题目描述: 做了A+B Problem,A/B Problem不是什么问题了 ...

  5. nyoj 844-A+B Problem(V) (string[::-1] 字符串反转)

    844-A+B Problem(V) 内存限制:64MB 时间限制:1000ms 特判: No 通过数:14 提交数:17 难度:1 题目描述: 做了A+B Problem之后,Yougth感觉太简单 ...

  6. nyoj 477-A+B Problem III (fabs() <= 0.00001)

    477-A+B Problem III 内存限制:64MB 时间限制:1000ms 特判: No 通过数:18 提交数:34 难度:1 题目描述: 求A+B是否与C相等. 输入描述: T组测试数据. ...

  7. nyoj 103-A+B Problem II (python 大数相加)

    103-A+B Problem II 内存限制:64MB 时间限制:3000ms 特判: No 通过数:10 提交数:45 难度:3 题目描述: I have a very simple proble ...

  8. SOJ4480 Easy Problem IV (并查集)

    Time Limit: 3000 MS Memory Limit: 131072 K Description 据说 你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过六个人你就能够认识任 ...

  9. A+B Problem IV

    描述acmj最近发现在使用计算器计算高精度的大数加法时很不方便,于是他想着能不能写个程序把这个问题给解决了.   输入 包含多组测试数据每组数据包含两个正数A,B(可能为小数且位数不大于400) 输出 ...

随机推荐

  1. Mist 转移默认区块存储位置方法

    http://8btc.com/thread-35325-1-1.html 看了bunaifeiqq 发的帖子“Mist 转移区块存储位置方法”,综合帖子下面的发言,自己做了测试,可行.电脑系统win ...

  2. MySQL "java.lang.IllegalArgumentException: HOUR_OF_DAY: 2 -> 3" 问题解析

    抛出异常截图: 异常原因 系统时区原因. 解决办法 在数据库连接串加上 &serverTimezone=Asia/Shanghai 即可~ conn_str="jdbc:mysql: ...

  3. Log4js 工作原理及代码简析

    本文地址 http://www.cnblogs.com/jasonxuli/p/6518650.html   log4js   版本 0.6.16, 最新版1.1.1 大体类似.   使用 log4j ...

  4. git clone,push,pull,fetch命令详解

    源自 Git是目前最流行的版本管理系统,学会Git几乎成了开发者的必备技能. Git有很多优势,其中之一就是远程操作非常简便.本文详细介绍5个Git命令,它们的概念和用法,理解了这些内容,你就会完全掌 ...

  5. linux下强制退出指定用户开启的伪终端

    一.环境 发行版:Ubuntu 18.04.1 LTS 代号:bionic 内核版本:4.15.0-30-generic 二.背景 每次通过ssh登陆服务器,但是超时后自动断开了与服务器的连接,因此在 ...

  6. 使用awk分割字符串并且获取分割后的最后一个字符串

    示例:从字符串"you-me-he"中获取he echo "you-me-he" |awk -F '[-]' '{print $NF}'

  7. Thinking in java note1

    Part information collecting from http://blog.csdn.net/leonliu06/article/details/78638841 1. 如果已经定义了一 ...

  8. Nginx 正则匹配

    目录 Nginx 正则表达式之匹配操作符 过期缓存 针对浏览器 针对文件类型 针对文件夹 判断文件,文件夹 设置某些类型文件的浏览器缓存时间 匹配到所有uri 全局变量 常用正则 Nginx 正则表达 ...

  9. 定义 S4 类

    S3 类仅用一个字符向量表示,与之不同的是,S4 类要求对类和方法有正式定义.为了定义一个 S4 类,我们需要调用 setClass( ),并提供一种类成员的表示,这种表示被称为字段(slots).通 ...

  10. STL空间配置器那点事

    STL简介 STL(Standard Template Library,标准模板库),从根本上说,STL是一些“容器”的集合,这些“容器”有list,vector,set,map等,STL也是算法和其 ...