Codevs高精度入门(减法、加法和乘法)解题报告

题目:                                               

 

题目描述 Description

给出两个正整数A和B,计算A-B的值。保证A和B的位数不超过500位。

输入描述 Input Description

读入两个用空格隔开的正整数

输出描述 Output Description

输出A-B的值

样例输入 Sample Input

3 12

样例输出 Sample Output

-9

题目分析                                                           

C++整数数据范围:

char                          -128 ~ +127                                        (1 Byte)
short
                       -32767 ~ + 32768                
      (2 Bytes)
unsigned
short          0 ~ 65536   
                                    (2 Bytes)
int
                             -2147483648 ~ +2147483647        (4 Bytes)
unsigned
int           
 0 ~ 4294967295                           (4 Bytes)
long == int
long long
        
-9223372036854775808 ~
+9223372036854775807    (8 Bytes)
double             
1.7 x 10^308                                              (8
Bytes)

long long范围最大,能表示19位。Test Case大于20位就会发生溢出的问题,无法计算。

所以题目的数据可以选择用string来储存。

如:string str = “123”;//123 = 1 x 102
+ 2 x 101 + 3 x 100

指数位    ———— 下标(数的高位与下标高位相反)

系数位    ————

为了计算方便,将str转换为int[ ](我习惯用vector).然后用下标和值来进行加减法运算,先得到每一位的值,再进行处理(进位、借位)。

如:

vector<int>
maxv = { 1, 0, 0, 9 }      // 1000

vector<int>
maxv = { 2, 3 }         // 23

vector<int>
sub, add;

计算后:sub = {
1, 0, -2, 6 };

add = {
1, 0, 2, 12 };

处理后 : sub =
{ 0, 8, 8, 6 }    // 小于0,借位

add = { 1, 0,
3, 2 }    // 小于0,进位

输出:注意处理0。

减法

n  
计算:统一用大数减小数,如果输入被减数小于减数,交换它们,标记输出为负。按位相减即可,从低位高位皆可。

n  
转换:高位借位-1,本位+10变为正,依次循环。

加法与减法类似。

乘法,用两个循环,依次相乘做和,更新每一位的值。

这个算式是从数值高位开始算的(直接从vector
0开始),当然也可以按普通乘法计算从低位开始。然后再进行进位转换,注意大于100和大于10的进位。

/*

高精度减法法题目:  http://codevs.cn/problem/3115/

2015.5.5 shaonian.ding

*/

#include<iostream>

#include<vector>

#include<string>

usingnamespace std;

//string convert to vector<int> function

void strToInts(string str, vector<int>
&v){

int len = str.size();

for (int i = 0;
i < len; i++)

{

int c = str[i] - ‘0‘;

v.push_back(c);

}

}

int main(){

string maxStr,
minStr;//被减数,减数string.

/*test
case*/

//maxStr
= "1000";

//minStr
= "10";

/*Input
Data*/

cin
>> maxStr>>minStr;

/*code*/

vector<int>
maxv,minv;//max vector、min
vector

bool
isPositive = true;//差正负标记,用来最后输出

//如果减数小于被减数,交换位置他们。差标记为负数,isPositive
= false;

if
(maxStr.size() <= minStr.size()){

if
(maxStr.size() == minStr.size()){

for (int i = 0;
i < maxStr.size(); i++)

{

if
(maxStr[i] < minStr[i]){

swap(maxStr,
minStr);

isPositive
= false;

break;

}

}

}

else{

swap(maxStr,
minStr);

isPositive
= false;

}

};

//string
convert to ints

strToInts(maxStr,
maxv);

strToInts(minStr,
minv);

//maxv =
maxv - minv;高位开始减,得到序列max =
{1,0,-1,0}

for (int i = 0;
i < minv.size(); i++)

{

int j =
maxv.size() - minv.size()+i;

if
(i<minv.size()){

maxv[j]
= maxv[j] - minv[i];

}

}

//将包含负数的序列按借位方法变为正。max =
{0,9,9,0}

for (int i =
maxv.size()-1; i > 0; i--)

{

if
(maxv[i] < 0){

maxv[i]
+= 10;

maxv[i
- 1] -= 1;

}

}

/*输出*/

if
(!isPositive){

cout
<< "-";

}

if
(maxv[0] != 0){

cout
<< maxv[0];

}

for (int i = 1;
i < maxv.size(); i++)

{

cout
<< maxv[i];

}

return 0;

}

加法:

/*

高精度加法题目:http://codevs.cn/problem/3116/

2015.5.5 shaonian.ding

*/

#include<iostream>

#include<vector>

#include<string>

usingnamespace std;

//string convert to vector<int> function

void strToInts(string str, vector<int>
&v){

int len = str.size();

for (int i = 0;
i < len; i++)

{

int c = str[i] - ‘0‘;

v.push_back(c);

}

}

int main(){

string maxStr,
minStr;

/*test
case*/

//maxStr = "945";

//minStr = "59";

/*Input
Data*/

cin
>> maxStr >> minStr;

/*code*/

vector<int>
maxv, minv;//max vector、min
vector

if
(maxStr.size() <= minStr.size()){

swap(maxStr,
minStr);

};

//string
convert to ints

strToInts(maxStr,
maxv);

strToInts(minStr,
minv);

//maxv =
maxv - minv;高位开始加,得到序列max =
{9,9,14}

for (int i = 0;
i < minv.size(); i++)

{

int j =
maxv.size() - minv.size() + i;

maxv[j]
= maxv[j] + minv[i];

}

//max =
{9,9,14}

for (int i =
maxv.size() - 1; i > 0; i--)

{

if
(maxv[i] >= 10){//最多为19

maxv[i]
-= 10;

maxv[i
- 1] += 1;//i=1执行最后一次转换,maxv[0]可能等于10

}

}

/*输出*/

if
(maxv[0] != 10){//跳过最高位为0

cout
<< maxv[0];

}

else{

cout
<< "1" << 10 - maxv[0];

}

for (int i = 1;
i < maxv.size(); i++)

{

cout
<< maxv[i];

}

return 0;

}

乘法:

/*

高精度乘法题目:http://codevs.cn/problem/3117/

2015.5.5 shaonian.ding

*/

#include<iostream>

#include<vector>

#include<string>

usingnamespace std;

//string convert to vector<int> function

void strToInts(string str, vector<int>
&v){

int len = str.size();

for (int i = 0;
i < len; i++)

{

int c = str[i] - ‘0‘;

v.push_back(c);

}

}

int main(){

string maxStr,
minStr;

/*test case */

//maxStr = "123";

//minStr = "45";

//maxStr = "99";

//minStr = "99";

/*Input
Data*/

cin
>> maxStr >> minStr;

/*code*/

vector<int>
maxv, minv;//max vector、min
vector

//string
convert to ints

strToInts(maxStr,
maxv);

strToInts(minStr,
minv);

int n =
maxv.size() + minv.size();//乘积的位数(不会大于两乘数位数之和)。

vector<int>
mul(n, 0 );//保存乘积multiplication,用来输出。

/*

*tset1:mul
={ 0,4,13,22,15 }

*tset2:mul
={ 0,81,162,81}

*/

for (int i = 0;
i < minv.size(); i++)// min i 外循环

{

for (int j = 0;
j < maxv.size(); j++)//max j 内循环

{

mul[i
+ j+1] += maxv[j] * minv[i];//

}

}

/*

*test1:mul
= { 0,5,5,3,5 }

*test2:mul
= { 9,8,0,1 }

*/

for (int i =
mul.size() - 1; i > 0; i--)

{

if (mul[i]
>= 100){//最多为199

mul[i
- 1] += mul[i] / 10;//进位

mul[i]
-= mul[i] / 10 *10;

}elseif (mul[i]
>= 10){//最多为99

mul[i
- 1] += mul[i] / 10;

mul[i] -=
mul[i] / 10 * 10;

}

}

/*输出*/

if (mul[0]
!= 0){//跳过最高位为0

cout
<< mul[0];

}

for (int i = 1;
i < mul.size(); i++)

{

cout
<< mul[i];

}

return 0;

}

时间: 2024-10-16 08:49:29

Codevs高精度入门(减法、加法和乘法)解题报告的相关文章

POJ 1001 解题报告 高精度大整数乘法模版

题目是POJ1001 Exponentiation  虽然是小数的幂 最终还是转化为大整数的乘法 这道题要考虑的边界情况比较多 做这道题的时候,我分析了 网上的两个解题报告,发现都有错误,说明OJ对于错误的判断还不够严厉. 对边界情况的讨论其实应该是思维严密的表现,当然这并不能表明我写的一点错误都没有,只是多多分析一下还是很有好处的. #include <iostream> #include <fstream> #include <string> #include &l

[DataStructure]多项式加法与乘法--B.链表存储(适用于零元系数多的多项式)

数据结构大作业…… 发出来大家乐呵乐呵…… 一.问题描述 给出N个多项式,求他们的和与积 二.解题报告 基本思想:加法和乘法都是把得数项直接链接在链表后面,最后统一做一个Merge&Sort工作即可.方便又快捷. (1)建立存储结构 1 struct _Poly 2 { 3 int factor;//系数 4 int Index;//幂 5 struct _Poly* next;//下一节点 6 }; 7 _Poly* poly[MAXTIMES+1]; 8 int Sum[MAXTIMES+1

[DataStructure]多项式加法与乘法--A.数组存储(适用于零元系数少的多项式)

数据结构大作业…… 发出来大家乐呵乐呵…… 一.问题描述 给出N个多项式,求他们的和与积 二.解题报告 (1)建立存储结构 1 struct _Poly 2 { 3 double Data[MAXTIMES+1]; 4 int Times; 5 }; 6 struct _Poly Poly[N+1]; (2)主程序架构 1 int main() 2 { 3 int Sum; 4 cout<<"请输入要做运算的多项式数量"<<endl; 5 cin>>

大数加法、乘法

1 #include<iostream> 2 3 #include<stdio.h> 4 5 #include<string.h> 6 7 #define Len 3000//大数的长度 8 9 using namespace std; 10 11 int Input (char n[])//将大数读入的函数 12 13 { 14 15 char s[Len]; 16 17 int i,l; 18 19 20 21 for(i=0; i<Len; i++) n[i

北京大学Online Judge 之 “求高精度幂(ID1001)”解题报告

北京大学Online Judge 之 "求高精度幂(ID1001)"解题报告 巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) 题目描述: Description 对数值很大.精度很高的数进行高精度计算是一类十分常见的问题.比如,对国债进行计算就是属于这类问题. 现在要你解决的问题是:对一个实数R( 0.0 < R <99.999 ),要求写程序精确计算 R 的 n 次方(Rn),其中n 是整数并且 0 < n <

一个基础而奇怪的问题:算法执行加法、乘法、除法性能无区别?

一个基础而奇怪的问题:算法执行加法.乘法.除法性能无区别? 计算机原理分析觉得:加法.乘法和除法的计算性能依次减少,但减少到什么程度? 编写C程序用30次百万数据计算来測试时间差异性,代码例如以下: #include <stdio.h> #include <stdlib.h> #include <time.h> #define N 1000000 void add(float x[], long n) { float sum = 0; for(long i = 0; i

数据结构第二次上机实验【链表实现多项式的加法和乘法】

利用链表实现一元多项式的加法和乘法 #define null 0 #include "stdio.h" #include "stdlib.h" #include "math.h" int op; typedef struct { float coef;//系数 int expn;//指数 }term; typedef struct Lnode { term data; Lnode *next; }*Link,*Linklist; int cmp(

3116 高精度练习之加法

3116 高精度练习之加法 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 给出两个正整数A和B,计算A+B的值.保证A和B的位数不超过500位. 输入描述 Input Description 读入两个用空格隔开的正整数 输出描述 Output Description 输出A+B的值 样例输入 Sample Input 3 12 样例输出 Sample Output 15 数据范围及提示 Data Size & Hint

习题:codevs 1035 火车停留解题报告

本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润,让你来求一种安排方法,使得车站收益最大,并输出收益值. 蒟蒻的思路是这样的: 一眼看出:最大费用最大流(MCMF)显然cost:表示车站收益然后……以车站为点建立图求流?同一个车站可能经过好几辆火车……,貌似很麻烦……:那么以什么建图.连边,还有怎么连?貌似有点类似于方格取数2之中的拆点……:那么