0
点赞
收藏
分享

微信扫一扫

51nod_1005 大数加法/HDU1753 大明A+B/poj1001(大数的加法/减法/乘法)


先系统的讲讲大数加法减法乘法的统一套路:

先贴代码:

大数加法

void BigAdd(char *adda,int lena,char *addb,int lenb,char sum[]){
int i,j,lensum;
lensum=lena>lenb?lena:lenb;
char *result,final[N];
lensum++;
result=(char *)calloc(lensum,1);
lensum--;
for(i=0;i<lena;i++)
adda[i]-='0';
for(i=0;i<lenb;i++)
addb[i]-='0';
for(i=0;i<lena&&i<lenb;i++)
result[i]=adda[lena-i-1]+addb[lenb-i-1];
if(lena>lenb)
for(i=lenb;i<lena;i++)
result[i]=adda[lena-i-1];
if(lena<lenb)
for(i=lena;i<lenb;i++)
result[i]=addb[lenb-i-1];
for(i=0;i<lensum;i++){
if(result[i]>9){
int t=result[i]/10;
result[i]%=10;
result[i+1] += t ;
}
}
j=0;
if(result[lensum]!=0){
final[j]=result[lensum]+'0';
j++;
}
for(i=lensum-1;i>=0;i--)
final[j++]=result[i]+'0';

final[j]='\0';
strcpy(sum,final);
}

大数减法:

void BigSub(char *suba,int lena,char *subb,int lenb,char sum[]){  
int lensum,num='0';
int i,j,k,tmp;
lensum=lena>lenb?lena:lenb;
for(i=0;i<lena;i++){
suba[i]=suba[i]-num;
}
for(i=0;i<lenb;i++){
subb[i]=subb[i]-num;
}
char *result,final[N];
result=(char*)calloc(lensum,1);
for(i=0,j=0;i<lena&&j<lenb;i++,j++){
result[i]=suba[lena-i-1]-subb[lenb-i-1];
}
if(lena>lenb){
for(i=lenb;i<lena;i++){
result[i]=suba[lena-i-1];
}
}
if(lenb>lena){
for(i=lena;i<lenb;i++){
result[i]=subb[lenb-i-1];
}
}
for(k=0;k<lensum-1;k++){
if(result[k]<0){
result[k]=result[k]+10;
result[k+1]-=1;
}
}
j=0;
if(result[lensum-1]!=0){
final[j]=result[lensum-1]+num;
j++;
}
for(i=lensum-2;i>=0;i--)
final[j++]=result[i]+num;

final[j]='\0';
strcpy(sum,final);
}

大数乘法:

void bigmul(char *f,int lena,char *m,int lenb,char *final){
int i,j,k,tmp_result,lensum;
lensum=lena+lenb;
for(i=0;i<lena;i++)
f[i]-='0';
for(i=0;i<lenb;i++)
m[i]-='0';
char *result;
result=(char *)calloc((lensum+1),sizeof(char));
for(i=0;i<lena;i++){
for(j=0;j<lenb;j++){
tmp_result=f[lena-i-1]*m[lenb-j-1];
result[i+j]+=tmp_result;
}
for(k=0;k<=i+j-1;k++){
if(result[k]>9){
int item;
item=result[k]/10;
result[k]%=10;
result[k+1]+=item;
}
}
}
j=0;
if(result[lensum-1]!=0){
final[j++]=result[lensum-1]+'0';
}

for(i=lensum-2;i>=0;i--){
final[j++]=result[i]+'0';
}
final[j]='\0';
}

这三个代码比较,你会发现他们的共同之处:

首先对传进来的两个字符串作处理,在逆序相加存储在result数组里面,然后对result数组处理即可。三个代码,只有对result数组的处理不同。

这样得出来的答案一般含有前导0,所有你需要一个函数除去前导0

void f(char sum[])
{
char a[N];
strcpy(a,sum);
int i;
int flag=0;
int len=strlen(a);
for(i=0;i<len;i++)
if(a[i]!='0')
{
flag=1;
break;
}
if(flag==0)
{
strcpy(sum,"0");
}else{
char s[N];
int t;
for(i=0;i<len;i++)
{
if(a[i]!='0')
{
t=i;
break;
}
}
int j=0;
for(i=t;i<len;i++)
{
s[j++]=a[i];
}
s[j]='\0';
strcpy(sum,s);
}
}

大数加法

给出2个大整数A,B,计算A+B的结果。

Input

第1行:大数A
第2行:大数B
(A,B的长度 <= 10000 需注意:A B有可能为负数)

Output

输出A + B

Sample Input

68932147586
468711654886

Sample Output

537643802472

题解:这一题很明显是考察大数的加法和减法,但是这种题却最不容易做,很是让人头痛,博主也是写了半天才AC。因为测试数据很杂,只有细心分好类,才能AC。主要去掉前导0.

比如测试数据:00001 0000003,0 -0,100 -99,10000 -999

具体代码如下:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 10010
void BigAdd(char *adda,int lena,char *addb,int lenb,char sum[]){//加法
int i,j,lensum;
lensum=lena>lenb?lena:lenb;
char *result,final[N];
lensum++;
result=(char *)calloc(lensum,1);
lensum--;
for(i=0;i<lena;i++)
adda[i]-='0';
for(i=0;i<lenb;i++)
addb[i]-='0';
for(i=0;i<lena&&i<lenb;i++)
result[i]=adda[lena-i-1]+addb[lenb-i-1];
if(lena>lenb)
for(i=lenb;i<lena;i++)
result[i]=adda[lena-i-1];
if(lena<lenb)
for(i=lena;i<lenb;i++)
result[i]=addb[lenb-i-1];
for(i=0;i<lensum;i++){
if(result[i]>9){
int t=result[i]/10;
result[i]%=10;
result[i+1] += t ;
}
}
j=0;
if(result[lensum]!=0){
final[j]=result[lensum]+'0';
j++;
}
for(i=lensum-1;i>=0;i--)
final[j++]=result[i]+'0';

final[j]='\0';
strcpy(sum,final);
}
void BigSub(char *suba,int lena,char *subb,int lenb,char sum[]){ //减法
int lensum,num='0';
int i,j,k,tmp;
lensum=lena>lenb?lena:lenb;
for(i=0;i<lena;i++){
suba[i]=suba[i]-num;
}
for(i=0;i<lenb;i++){
subb[i]=subb[i]-num;
}
char *result,final[N];
result=(char*)calloc(lensum,1);
for(i=0,j=0;i<lena&&j<lenb;i++,j++){
result[i]=suba[lena-i-1]-subb[lenb-i-1];
}
if(lena>lenb){
for(i=lenb;i<lena;i++){
result[i]=suba[lena-i-1];
}
}
if(lenb>lena){
for(i=lena;i<lenb;i++){
result[i]=subb[lenb-i-1];
}
}
for(k=0;k<lensum-1;k++){
if(result[k]<0){
result[k]=result[k]+10;
result[k+1]-=1;
}
}
j=0;
if(result[lensum-1]!=0){
final[j]=result[lensum-1]+num;
j++;
}
for(i=lensum-2;i>=0;i--)
final[j++]=result[i]+num;

final[j]='\0';
strcpy(sum,final);
}
void f(char sum[])//去掉前导0
{
char a[N];
strcpy(a,sum);
int i;
int flag=0;
int len=strlen(a);
for(i=0;i<len;i++)
if(a[i]!='0')
{
flag=1;
break;
}
if(flag==0)
{
strcpy(sum,"0");
}else{
char s[N];
int t;
for(i=0;i<len;i++)
{
if(a[i]!='0')
{
t=i;
break;
}
}
int j=0;
for(i=t;i<len;i++)
{
s[j++]=a[i];
}
s[j]='\0';
strcpy(sum,s);
}
}
int main()
{
char a[N],b[N];
scanf("%s",a);
scanf("%s",b);
char sum[N];
if(a[0]=='-')
{
char *p=a;
char num[N];
strcpy(num,p+1);
strcpy(a,num);
if(b[0]=='-')
{
char *p=b;
char num[N];
strcpy(num,p+1);
strcpy(b,num);
int lena,lenb;
lena=strlen(a);
lenb=strlen(b);
BigAdd(a,lena,b,lenb,sum);
f(sum);
if(strcmp(sum,"0")==0)
printf("0\n",sum);
else
printf("-%s\n",sum);
}
else
{
int lena,lenb;
lena=strlen(a);
lenb=strlen(b);
if(lena>lenb)//a大
{
BigSub(a,lena,b,lenb,sum);
f(sum);
printf("-%s\n",sum);
}else if(lena<lenb)//a小
{
BigSub(b,lenb,a,lena,sum);
f(sum);
printf("%s\n",sum);
}else{
if(strcmp(a,b)>0)//a大
{
BigSub(a,lena,b,lenb,sum);
f(sum);
printf("-%s\n",sum);
}else if(strcmp(a,b)<0)//a小
{
BigSub(b,lenb,a,lena,sum);
f(sum);
printf("%s\n",sum);
}else{
printf("0\n");
}
}
}
}else//a为正
{
if(b[0]=='-')
{
char *p=b;
char num[N];
strcpy(num,p+1);
strcpy(b,num);
int lena,lenb;
lena=strlen(a);
lenb=strlen(b);
if(lena>lenb)//a大
{
BigSub(a,lena,b,lenb,sum);
f(sum);
printf("%s\n",sum);
}else if(lena<lenb)//a小
{
BigSub(b,lenb,a,lena,sum);
f(sum);
printf("-%s\n",sum);
}else
{
if(strcmp(a,b)>0)//a大
{
BigSub(a,lena,b,lenb,sum);
f(sum);
printf("%s\n",sum);
}else if(strcmp(a,b)<0){//a小
BigSub(b,lenb,a,lena,sum);
f(sum);
printf("-%s\n",sum);
}else{
printf("0\n");
}
}
}else
{
int lena,lenb;
lena=strlen(a);
lenb=strlen(b);
BigAdd(a,lena,b,lenb,sum);
f(sum);
printf("%s\n",sum);
}
}
return 0;
}

大明A+B

话说,经过了漫长的一个多月,小明已经成长了许多,所以他改了一个名字叫“大明”。
这时他已经不是那个只会做100以内加法的那个“小明”了,现在他甚至会任意长度的正小数的加法。

现在,给你两个正的小数A和B,你的任务是代表大明计算出A+B的值。

Input

本题目包含多组测试数据,请处理到文件结束。
每一组测试数据在一行里面包含两个长度不大于400的正小数A和B。

Output

请在一行里面输出输出A+B的值,请输出最简形式。详细要求请见Sample Output。

Sample Input

1.1 2.9
1.1111111111 2.3444323343
1 1.1

Sample Output

4
3.4555434454
2.1

题解:将整数部分和小数部分分开来算,然后考虑小数进位的问题,还有要注意去掉小数后导0.

具体代码如下:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
#define N 600
using namespace std;
void BigAdd(char *adda,int lena,char *addb,int lenb,char sum[]){//整数部分加法
int i,j,lensum;
lensum=lena>lenb?lena:lenb;
char *result,final[N];
lensum++;
result=(char *)calloc(lensum,1);
lensum--;
for(i=0;i<lena;i++)
adda[i]-='0';
for(i=0;i<lenb;i++)
addb[i]-='0';
for(i=0;i<lena&&i<lenb;i++)
result[i]=adda[lena-i-1]+addb[lenb-i-1];
if(lena>lenb)
for(i=lenb;i<lena;i++)
result[i]=adda[lena-i-1];
if(lena<lenb)
for(i=lena;i<lenb;i++)
result[i]=addb[lenb-i-1];
for(i=0;i<lensum;i++){
if(result[i]>9){
int t=result[i]/10;
result[i]%=10;
result[i+1] += t ;
}
}
j=0;
if(result[lensum]!=0){
final[j]=result[lensum]+'0';
j++;
}
for(i=lensum-1;i>=0;i--)
final[j++]=result[i]+'0';

final[j]='\0';
strcpy(sum,final);
}
void SmallAdd(char *adda,int lena,char *addb,int lenb,char sum[])//小数部分加法
{
char *result;
int lensum=lena>lenb?lena:lenb;
lensum++;
result=(char *)calloc(lensum,1);
lensum--;
int i;
for(i=0;i<lena;i++)
adda[i]-='0';
for(i=0;i<lenb;i++)
addb[i]-='0';
int lenmin=lena<lenb?lena:lenb;
for(i=0;i<lenmin;i++)
result[i]=adda[lenmin-i-1]+addb[lenmin-i-1];
for(i=0;i<lenmin;i++)
if(result[i]>9)
{
result[i+1]++;
result[i]%=10;
}
int j;
j=0;
char final[N];
if(result[lenmin]!=0)
{
final[j]=result[lenmin]+'0';
j++;
}
for(i=lenmin-1;i>=0;i--)
final[j++]=result[i]+'0';
if(lena>lenb)
for(i=lenmin;i<lena;i++)
final[j++]=adda[i]+'0';
if(lena<lenb)
for(i=lenmin;i<lenb;i++)
final[j++]=addb[i]+'0';
final[j]='\0';
strcpy(sum,final);
}
int main()
{
char num1[N],num2[N];
while(scanf("%s%s",num1,num2)!=EOF)
{
char a[N],b[N];//存储小数部分
char a1[N],b1[N];//存储整数部分
char *p=strchr(num1,'.');
char *q=strchr(num2,'.');
if(p)
{
strcpy(a,p+1);
*p='\0';
strcpy(a1,num1);
}
else
{
sscanf("0","%s",a);
strcpy(a1,num1);
}
if(q)
{
strcpy(b,q+1);
*q='\0';
strcpy(b1,num2);
}
else
{
sscanf("0","%s",b);
strcpy(b1,num2);
}
int lena=strlen(a);
int lenb=strlen(b);
char sum2[N],sum1[N];//加完后的值
SmallAdd(a,lena,b,lenb,sum2);//小数相加
int lena1=strlen(a1);
int lenb1=strlen(b1);
int len=strlen(sum2);
int flag=0,temp=0;
if(len!=lena&&len!=lenb)//如果小数进位了
{ temp=1;
a1[lena1-1]++;
char *p=sum2,sum3[N];
p++;
strcpy(sum3,p);
strcpy(sum2,sum3);
for(int i=0;i<strlen(sum2);i++)
if(sum2[i]!='0')
{
flag=1;//说明不全是0
break;
}
if(flag==1)
for(int i=strlen(sum2)-1;i>=10;i--)
if(sum2[i]!='0')
{
sum2[i+1]='\0';
break;
}
}
else{
for(int i=0;i<strlen(sum2);i++)
if(sum2[i]!='0')
{
flag=1;//说明不全是0
break;
}
if(flag==1)
for(int i=strlen(sum2)-1;i>=10;i--)
if(sum2[i]!='0')
{
sum2[i+1]='\0';
break;
}
}
BigAdd(a1,lena1,b1,lenb1,sum1);//整数相加
if(temp==1)//进位了
{
if(flag==1)
printf("%s.%s\n",sum1,sum2);
else
printf("%s\n",sum1);
}else{//没进位
if(flag==1)
printf("%s.%s\n",sum1,sum2);
else
printf("%s\n",sum1);
}




}
return 0;
}

Exponentiation

Problems involving the computation of exact values of very large magnitude and precision are common. For example, the computation of the national debt is a taxing experience for many computer systems.

This problem requires that you write a program to compute the exact value of R n where R is a real number ( 0.0 < R < 99.999 ) and n is an integer such that 0 < n <= 25.

Input

The input will consist of a set of pairs of values for R and n. The R value will occupy columns 1 through 6, and the n value will be in columns 8 and 9.

Output

The output will consist of one line for each line of input giving the exact value of R^n. Leading zeros should be suppressed in the output. Insignificant trailing zeros must not be printed. Don't print the decimal point if the result is an integer.

Sample Input

95.123 12
0.4321 20
5.1234 15
6.7592 9
98.999 10
1.0100 12

Sample Output

548815620517731830194541.899025343415715973535967221869852721
.00000005148554641076956121994511276767154838481760200726351203835429763013462401
43992025569.928573701266488041146654993318703707511666295476720493953024
29448126.764121021618164430206909037173276672
90429072743629540498.107596019456651774561044010001
1.126825030131969720661201

大概题意就是每行一个R一个N,求R^N.

题解:这一题应该是这三道题里面最好过的一道,先把小数点去掉,求出乘积的值,最后根据小数点后面的位数,在输出的时候把小数点加上就OK了。还有是要注意前导0和后导0的问题。

具体代码如下:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
#define N 6000
using namespace std;
void bigmul(char *f,char *m,char *final){//大数乘法
int i,j,k,tmp_result,lensum;
int lena=strlen(f);
int lenb=strlen(m);
lensum=lena+lenb;
for(i=0;i<lena;i++)
f[i]-='0';
for(i=0;i<lenb;i++)
m[i]-='0';
char *result;
result=(char *)calloc((lensum+1),sizeof(char));
for(i=0;i<lena;i++){
for(j=0;j<lenb;j++){
tmp_result=f[lena-i-1]*m[lenb-j-1];
result[i+j]+=tmp_result;
}
for(k=0;k<=i+j-1;k++){
if(result[k]>9){
int item;
item=result[k]/10;
result[k]%=10;
result[k+1]+=item;
}
}
}
j=0;
if(result[lensum-1]!=0){
final[j++]=result[lensum-1]+'0';
}

for(i=lensum-2;i>=0;i--){
final[j++]=result[i]+'0';
}
final[j]='\0';
}
void fa(char sum[])//去前导0
{
char a[N];
strcpy(a,sum);
int i;
int flag=0;
int len=strlen(a);
for(i=0;i<len;i++)
if(a[i]!='0')
{
flag=1;
break;
}
if(flag==0)
{
strcpy(sum,"0");
}else{
char s[N];
int t;
for(i=0;i<len;i++)
{
if(a[i]!='0')
{
t=i;
break;
}
}
int j=0;
for(i=t;i<len;i++)
{
s[j++]=a[i];
}
s[j]='\0';
strcpy(sum,s);
}
}
void fb(char sum[])//去后导0
{
char a[N];
int len2=strlen(sum);
int i,j;
for(i=0;i<len2;i++)
a[i]=sum[len2-i-1];
a[i]='\0';
int flag=0;
int len=strlen(a);
for(i=0;i<len;i++)
if(a[i]!='0')
{
flag=1;
break;
}
if(flag==0)
{
strcpy(sum,"0");
}else{
char s[N];
int t;
for(i=0;i<len;i++)
{
if(a[i]!='0')
{
t=i;
break;
}
}
int j=0;
for(i=t;i<len;i++)
{
s[j++]=a[i];
}
s[j]='\0';
int len1=strlen(s);
for(i=0;i<len1;i++)
a[i]=s[len1-i-1];
a[i]='\0';
strcpy(sum,a);
}
}
int main()
{
char num1[N];
int n;
while(scanf("%s%d",num1,&n)!=EOF)
{
char b[N];//存储小数部分
char a[N];//存储整数部分
char final[N];//存储最终答案
strcpy(final,"1");
char *p=strchr(num1,'.');
if(p)
{
strcpy(b,p+1);
*p='\0';
strcpy(a,num1);
}else{
strcpy(a,num1);
strcpy(b,"0");
}
fb(b);
fa(a);
if(strcmp(a,"0")==0)
{
if(strcmp(b,"0")==0)
cout<<"0"<<endl;
else//.123456
{
int lena=strlen(b)*n;
for(int i=0;i<n;i++)
{
char p[N],q[N];
strcpy(p,final);
strcpy(q,b);
bigmul(p,q,final);
}
int lenb=strlen(final);
cout<<".";
for(int i=0;i<lena-lenb;i++)
cout<<"0";
cout<<final<<endl;
}
}else{
if(strcmp(b,"0")==0)
{
for(int i=0;i<n;i++)
{

char p[N],q[N];
strcpy(p,final);
strcpy(q,a);
bigmul(p,q,final);
}
cout<<final<<endl;
}else{
char aa[N];
sprintf(aa,"%s%s",a,b);
int len1=strlen(b)*n;
for(int i=0;i<n;i++)
{
char p[N],q[N];
strcpy(p,final);
strcpy(q,aa);
bigmul(p,q,final);
}
int len2=strlen(final);
for(int i=0;i<len2-len1;i++)
printf("%c",final[i]);
printf(".");
for(int i=len2-len1;i<len2;i++)
printf("%c",final[i]);
printf("\n");
}
}
}
return 0;
}

高精度的题还是需要细心细心在细心才能AC呀!

举报

相关推荐

0 条评论