NYOJ A+B Problem IV 高精度正实数加法

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

高精度的正实数大数加法,需要考虑的东西很多,加油,200块之路。


#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<ctime>
#include<string>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#include<set>
#include<map>
#include<cstdio>
#include<limits.h>
#define MOD 1000000007
#define fir first
#define sec second
#define fin freopen("/home/ostreambaba/文档/input.txt", "r", stdin)
#define fout freopen("/home/ostreambaba/文档/output.txt", "w", stdout)
#define mes(x, m) memset(x, m, sizeof(x))
#define Pii pair<int, int>
#define Pll pair<ll, ll>
#define INF 1e9+7
#define Pi 4.0*atan(1.0)
#define lowbit(x) (x&-x)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-7;
const int MAX = 101;
using namespace std;
#define time
bool isZero(const string str)   //判断小数部分字符串是否都为0
{
    int num;
    sscanf(str.c_str(), "%d", &num);
    if(0 == num){
        return true;
    }
    return false;
}
int main()
{
    string s1, s2, s3, s4;  //s1,s2代表整数部分, s3,s4代表小数部分
    while(cin >> s1 >> s2){
        int pos, flag = 0; //flag表示小数部分相加是否会大于等于1,大于则flag = 1, pos代表小数点的位置
        pos = s1.find(".");
        s3 = s1.substr(pos+1, s1.size());  //提取小数点部分
        s1 = s1.substr(0, pos); 
        if(pos == -1){ //若没有小数点部分,则直接赋值为0
            s3 = "0";
        }
        pos = s2.find("."); //同上
        s4 = s2.substr(pos+1, s2.size());
        if(pos == -1){
            s4 = "0";
        }
        s2 = s2.substr(0, pos);
        int mlen = min(s3.size(), s4.size());  //小数部分相加
        if(s3.size() < s4.size()){  //以长度较长的字符串作为标准
            string tmp = s3;
            s3 = s4;
            s4 = tmp;
        }
        if(s1.size() < s2.size()){ //同上
            string tmp = s1;
            s1 = s2;
            s2 = tmp;
        }
        for(int i = mlen - 1; i >= 0; --i){  //小数部分相加
            s3[i] += s4[i] - '0';
            if(s3[i] > '9'){  
                if(i == 0){   //当最大的位置相加大于9
                    s3[i] -= 10;
                    flag = 1;//则整数部分+1
                    break; 
                }
                s3[i] -= 10;   //不是最大位置则进行进行加法 
                s3[i-1] += 1;  //进位
            }
        }
        int minlen = min(s1.size(), s2.size());   //整数部分相加,从s1,s2尾部开始相加,maxlen代表较长的字符串, minlen代表较短的字符串
        int maxlen = max(s1.size(), s2.size());
        string str = "1";  //整数部分最大位置大于9 则 +1
        for(int i = minlen - 1, j = maxlen - 1; i >= 0; --i, --j){  //字符串相加
            s1[j] += s2[i] - '0';
            if(s1[j] > '9'){     // 大于9,分情况
                if(i == 0 && j == 0){   // 两字符串长度恰好相同, 如9+1=10
                    if(s1[j] > '9'){    //因为怕越界,所以直接s1之前加1  
                        s1[j] -= 10;
                        s1 = str + s1;  // 1+XXXX
                        break; 
                    }
                }
                else if(i == 0 && j != 0){  //两长度不一样,一样的步骤
                      s1[j] -= 10;
                      s1[j-1] += 1;
                      for(int k = j-1; k >= 0; --k){
                           if(s1[k] > '9'){
                             if(k == 0){  // 这里就考虑到  999+1 = 10000,思想同上
                                 s1[k] -= 10;
                                 string str = "1";
                                 s1 = str + s1;
                                 break;
                             }
                             s1[k] -= 10;
                             s1[k-1] += 1;
                        }
                    }
                }
                if(i != 0){   //因为上面if(i==0)那步break跳出循环就不下需要执行了,所以这里要加限定条件, 不然会再执行一次会出错
                    s1[j] -= 10;
                    s1[j-1] += 1;
                }
            }
        }
      // cout << s1 << endl;
        if(flag == 1){  //整数部分+1  和上面差不多, 需要考虑 999+1
            s1[s1.size()-1] += flag;
            if(s1[s1.size()-1] > '9'){
                for(int i = s1.size()-1; i >= 0; --i){
                    if(s1[i] > '9'){
                        if(0 == i){
                            s1[i] -= 10;
                            s1 = str + s1;
                            break;
                        }
                        s1[i] -= 10;
                        s1[i-1] += 1;
                    }
                }
            }
        }
        if(!isZero(s3)){  //判断小数部分是否为0,为0则不输出
            int k = s3.size();
            while(s3[--k] == '0');  //去掉多余的0
            s3 = s3.substr(0, k+1);
            //cout << s3 << endl;
            cout << s1 << "." << s3 << endl;
        }
        else{
            cout << s1 << endl;
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
x1y2 x2y3 x3y1-x1y3-x2y1-x3y2 是计算三角形面积的公式中的一部分。 在这个公式中,x1、x2、x3分别表示三角形的三个顶点的x坐标,y1、y2、y3分别表示三角形的三个顶点的y坐标。通过计算这个表达式的值,可以得到三角形的面积。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [TetraCluster:使用并行Java 2库的Java并行程序。 该程序在群集并行计算机上运行,​​以从给定的点集中找到...](https://download.csdn.net/download/weixin_42171208/18283141)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [线性代数有个题,求交变换x=Qy,化二次型f(x1,x2,x3)=8x1x2+8x1x3+8x2x3为标准型求出特征值](https://blog.csdn.net/weixin_39956182/article/details/115882118)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [nyoj-67-三角形面积(S=(1/2)*(x1y2+x2y3+x3y1-x1y3-x2y1-x3y2))](https://blog.csdn.net/weixin_30492601/article/details/99541033)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值