一、大数相乘
#include <cstdio> #include <cstring> #include <string> #include <cmath> #include <algorithm> #include <iostream> using namespace std; int main() { char chr1[100],chr2[100]; int len1,len2; while(scanf("%s %s",chr1,chr2)) { int i,j=0,k=0,s; int a[110]={0},b[110]={0},c[220]={0}; len1=strlen(chr1); len2=strlen(chr2); for(i=len1-1,j=0;i>=0;i--) a[j++]=chr1[i]-'0'; for(i=len2-1,k=0;i>=0;i--) b[k++]=chr2[i]-'0'; for(i=0;i<len1;i++) { for(s=0;s<len2;s++) { c[i+s]=c[i+s]+a[i]*b[s]; } } for(i=0;i<200;i++) { if(c[i]>=10){ c[i+1]=c[i+1]+c[i]/10; //这一步和下面一步位置不要写反了 c[i]=c[i]%10; } } for(i=200;i>0;i--) { if(c[i]==0) continue; else break; } for(;i>=0;i--) cout<<c[i]; cout<<endl; } return 0; }
二、大数相除(取模,取余)(没有看懂)
#include<stdio.h> #include<string.h> char a[100],b[100];//用两个字符串用来输入两个大数 int x[100],y[100],z[100],m[100];//被除数 除数 商 余数 int digit;//大数的位数 void sub(int x[],int y[],int len1,int len2)//大数减法 { int i; for(i=0;i<len1;i++) { if(x[i]<y[i]) { x[i]=x[i]+10-y[i]; x[i+1]--; } else x[i]=x[i]-y[i]; } for(i=len1-1;i>=0;i--)//判断减法结束之后,被除数的位数 { if(x[i]) { digit=i+1; break; } } } int judge(int x[],int y[],int len1,int len2) { int i; if(len1<len2) return -1; if(len1==len2)//若两个数位数相等 { for(i=len1-1;i>=0;i--) { if(x[i]==y[i])//对应位的数相等 continue; if(x[i]>y[i])//被除数 大于 除数,返回值为1 return 1; if(x[i]<y[i])//被除数 小于 除数,返回值为-1 return -1; } return 0;//被除数 等于 除数,返回值为0 } } int main() { int i,j=0,k=0,temp; int len1,len2,len;//len两个大数位数的差值 while(~scanf("%s %s",a,b)) { len1=strlen(a);//被除数位数 len2=strlen(b);//除数位数 for(i=len1-1,j=0;i>=0;i--)//将字符串中各个元素倒序储存在数组中 x[j++]=a[i]-'0'; for(i=len2-1,k=0;i>=0;i--) y[k++]=b[i]-'0'; if(len1<len2)//当被除数位数 小于 除数位数时 { printf("商是:0 "); printf("余数是:"); puts(a); } else //当被除数位数 大于或者 除数位数时 { len=len1-len2;//两个大数位数的差值 for(i=len1-1;i>=0;i--)//将除数后补零,使得两个大数位数相同。被除数:4541543329 除数:98745,加零后:9874500000 { if(i>=len) y[i]=y[i-len]; else y[i]=0; } len2=len1;//将两个大数数位相同 digit=len1; //将原被除数位数赋值给digit for(j=0;j<=len;j++) { z[len-j]=0; while(((temp=judge(x,y,len1,len2))>=0)&&digit>=k)//判断两个数之间的关系以及位数与除数原位数的关系 { sub(x,y,len1,len2); //大数减法函数 z[len-j]++;//储存商的每一位 len1=digit;//重新修改被除数的长度 if(len1<len2&&y[len2-1]==0) len2=len1;//将len1长度赋给len2; } if(temp<0)//若被除数 小于 除数,除数减小一位。例如:被除数:4541543329 除数:(原)98745,(加零后)9874500000,后退一位后:0987450000 { for(i=1;i<len2;i++) y[i-1]=y[i]; y[i-1]=0; if(len1<len2) len2--; } } printf("商是:"); for(i=len;i>0;i--)//去掉前缀0 { if(z[i]) break; } for(;i>=0;i--) printf("%d",z[i]); printf(" "); printf("余数是:"); for(i=len1;i>0;i--) { if(x[i]) break; } for(;i>=0;i--) printf("%d",x[i]); printf(" "); } } return 0; }
三、大数阶乘(求位数)
法一:
lg(N!)=[lg(N*(N-1)*(N-2)*......*3*2*1)]+1 =[lgN+lg(N-1)+lg(N-2)+......+lg3+lg2+lg1]+1
#include<stdio.h> #include<math.h> int main() { int n; double sum=0; scanf("%d",&n); for(int i=1;i<=n;i++) { sum=sum+log10(i); } printf("%d ",(int)sum+1); return 0; }
法二:
log10(n!) = log10(2*PI*n)/2+n*log10(n/E);
故n!的位数= log10(2*PI*n)/2+n*log10(n/E)+1(注意:当n=1时,算得的结果为0)
#include<stdio.h> #include<math.h> #define PI 3.141592654 #define E 2.71828182846 int main() { int n,sum=1; scanf("%d",&n); if(n>3) sum=log10(2*PI*n)/2+n*log10(n/E)+1; printf("%d ",sum); return 0; }
四、大数阶乘(求值)
#include <cstdio> #include <iostream> using namespace std; int main() { int n,a[20001]; int temp,digit=1; a[0]=1; cin>>n; int i,j; for(i=2;i<=n;i++) { int num=0; for(j=0;j<digit;j++) { temp=a[j]*i+num; a[j]=temp%10; num=temp/10; } while(num) { a[digit]=num%10; num/=10; digit++; } } for(i=digit-1;i>=0;i--) cout<<a[i]; cout<<endl; return 0; }
五、大数相减
//大数相减 #include <cstdio> #include <cstring> #include <string> #include <iostream> #include <cmath> #include <algorithm> using namespace std; int x[100]={0},y[100]={0},z[100]={0}; void sub(int x[],int y[],int len) { for(int i=0;i<len;i++) { if(x[i]>=y[i]) z[i]=x[i]-y[i]; else if(x[i]<y[i]) { z[i]=x[i]+10-y[i]; x[i+1]=x[i+1]-1; } } for(int i=len-1;i>0;i--) { if(z[i]==0) len--; else break; } for(int i=len-1;i>=0;i--) cout<<z[i]; cout<<endl; } int main() { char chr1[100],chr2[100]; int len1,len2; while(scanf("%s %s",chr1,chr2)) { int i,j=0,k=0; len1=strlen(chr1); len2=strlen(chr2); for(i=len1-1,j=0;i>=0;i--) x[j++]=chr1[i]-'0'; for(i=len2-1,k=0;i>=0;i--) y[k++]=chr2[i]-'0'; if(len1>len2) sub(x,y,len1); else if(len1<len2) { printf("-"); sub(y,x,len2); } else if(len1==len2) { for(i=len1-1;i>=0;i--) { if(x[i]==y[i]) continue; else if(x[i]>y[i]) { sub(x,y,len1); break; } else if(x[i]<y[i]) { printf("-"); sub(y,x,len1); break; } } if(i==-1) sub(x,y,len1); } } return 0; }
六、大数相加
#include <cstdio> #include <cstring> #include <string> #include <iostream> #include <cmath> #include <algorithm> using namespace std; int main() { char chr1[100],chr2[100]; int a[100]={0},b[100]={0},c[100]={0}; int len1,len2,len; while(scanf("%s %s",chr1,chr2)) { int i,j=0,k=0; len1=strlen(chr1); len2=strlen(chr2); for(i=len1-1;i>=0;i--) { a[j]=chr1[i]-'0'; j++; } for(i=len2-1;i>=0;i--) { b[k]=chr2[i]-'0'; k++; } if(len1>len2) len=len1; else len=len2; int m=0; for(i=0;i<len;i++) { c[i]=(a[i]+b[i]+m)%10; if(a[i]+b[i]+m>=10) m=1; else m=0; } if(a[i-1]+b[i-1]+m>10) c[i]=1; else i=i-1; for(;i>=0;i--) cout<<c[i]; cout<<endl; } return 0; }