当我想敲高精加
天道好轮回,苍天饶过谁
今天机房里昊哥敲高精时我不厚道地笑了
结果好家伙,晚上就遇上一道用高精的题
我原来的代码
#include<bits/stdc++.h>
using namespace std;
int main(){
char m[11111],n[11111];
int a[11111]={0},b[11111]={0},c[11111]={0},i,x,y,flag,d=0;
scanf("%s%s",m,n);
x=strlen(m);
y=strlen(n);
for(i=0;i<x;i++){
a[i]=m[x-i-1]-'0';
}for(i=0;i<y;i++){
b[i]=n[y-i-1]-'0';
}if(x<y){
flag=y;
}else{
flag=x;
}for(i=0;i<flag;i++){
c[i]=(a[i]+b[i]+d)%10;
d=(a[i]+b[i]+d)/10;
}if(d!=0){
printf("%d",d);
}for(i=flag-1;i>=0;i--){
cout<<c[i];
}
return 0;
}
改进版代码
int n,f[5010][5010],len;
void jiafa(int k)//高精加法
{
for(int i=1; i<=len; i++)//两数相加
f[k][i]=f[k-1][i]+f[k-2][i];
for(int i=1; i<=len; i++)//进位
{
if(f[k][i]>=10)
{
f[k][i+1]+=f[k][i]/10;
f[k][i]=f[k][i]%10;
if(f[k][len+1]>0)len++;
}
}
}
int main()
{
cin>>n;
len=1;
f[1][1]=1;
f[2][1]=2;
for(int i=3; i<=n; i++)//开始计算
jiafa(i);
for(int i=len; i>=1; i--)//输出
cout<<f[n][i];
return 0;
}
f[1--k][i]num
f[k][1--i]进位
好吧,继这件事19天后,gg开始讲高精了,先仍然把范围限制在(花式)高精加上
然后吧,就有了两个神奇的东西
- 一个是把几个数组改成了结构体(比开二维省空间多了)
- 一个是万进制
点击查看代码1
struct bignum
{ int len,num[11111]; }a,b,c;
void num(string s,bignum &c)
{
reverse(s.begin(),s.end());
for(int i=0;i<s.size();i++)
{
c.num[i+1]=s[i]-'0';
}
c.len=s.size();
}
void gaojingjia(bignum a,bignum b)
{
if(a.len<b.len)int l=b.len;
else int l=a.len;
int d;
for(int i=1;i<=l;i++)
{
c.num[i]+=(a.num[i]+b.num[i]+d)%10;
d=c.num[i]/10;
}
if(c.num[l+1]!=0)l++;
c.len=l;
print(c);
}
void print(bignum c)
{
for(int i=c.len;i>0;i--)
{
printf("%d",c.num[i]);
}
}
点击查看代码2
#include<bits/stdc++.h>
using namespace std;
char m[11111],n[11111];
int a[11111]={0},b[11111]={0},c[11111]={0};
bool book[11111]={0};
int l1,l2,flag,d=0,j,k;
int main(){
scanf("%s%s",m,n);
l1=strlen(m);
l2=strlen(n);
j=0;
for(int i=0;i<l1;i+=5)
{
a[j]=10000*(m[l1-i-1]-'0');
a[j]=1000*(m[l1-i]-'0');
a[j]=100*(m[l1-i+1]-'0');
a[j]=10*(m[l1-i+2]-'0');
a[j]=m[l1-i+3]-'0';
j++
}
k=0;
for(int i=0;i<l2;i+=5)
{
b[k]=10000*(n[l2-i-1]-'0');
b[k]=1000*(n[l2-i]-'0');
b[k]=100*(n[l2-i+1]-'0');
b[k]=10*(n[l2-i+2]-'0');
b[k]=n[l2-i+3]-'0';
k++;
}
if(l1<l2)
{
flag=k;
}
else
{
flag=j;
}
for(int i=0;i<flag;i++){
c[i]=(a[i]+b[i]+d)%10000;
d=(a[i]+b[i]+d)/10000;
k++;
}
if(d!=0)
{
printf("%d",d);
}
printf("%d",a[flag-1]);//最高位不需要补零;
for(i=k-1;i>=1;--i)//从第二个元素
{
if(a[i]>=1000)//若该元素是四位数,则原样输出
printf("%d",a[i]);
else if(a[i]>=100&&a[i]<1000)//若该元素为三位数,补一个0;
printf("0%d",a[i]);
else if(a[i]>=10&&a[i]<100)//补两个;
printf("00%d",a[i]);
else//补三个;
printf("000%d",a[i]);
}
return 0;
}
点击查看高精减(注意前补0)
#include<bits/stdc++.h>
using namespace std;
char m[11111],n[11111];
int a[11111]={0},b[11111]={0},i,x,y,flag=1;
int main(){
cin>>m>>n;
x=strlen(m);
y=strlen(n);
for(i=0;i<x;i++){
a[i]=m[x-i-1]-'0';
}for(i=0;i<y;i++){
b[i]=n[y-i-1]-'0';
}if(x<y){
flag=0;
}else if(x>y){
flag=1;
}else{
for(int j=y-1;j>=0;j--){
if(b[j]>a[j]){
flag=0;
break;
}else if(a[j]>b[j]){
flag=1;
break;
}else{
flag=2;
}
}
}
if(flag==0){
printf("-");
for(i=0;i<y;i++){
b[i]=b[i]-a[i];
if(b[i]<0){
b[i]=b[i]+10;
b[i+1]--;
}
}i=y-1;
while(b[i]==0){
i--;
}for(;i>=0;i--){
cout<<b[i];
}
}else if(flag==2){
printf("0");
}else{
for(i=0;i<x;i++){
a[i]=a[i]-b[i];
if(a[i]<0){
a[i]=a[i]+10;
a[i+1]--;
}
}i=x-1;
while(a[i]==0){
i--;
}for(;i>=0;i--){
cout<<a[i];
}
}
return 0;
}
点击查看高精乘(双高精)
#include<bits/stdc++.h>
using namespace std;
int l1,l2,a[11111],b[11111],c[11111],d;
char m[11111]=,n[11111]=;
int main(){
cin>>m>>n;
l1=strlen(m);
l2=strlen(n);
for(int i=1;i<=l1;++i)
{
a[i]=m[l1-i]-'0';
}
for(int i=1;i<=l2;++i)
{
b[i]=n[l2-i]-'0';
}
for(int i=1;i<=l1;++i)
{
for(j=1;j<=l2;++j)
{
c[i+j-1]+=a[i]*b[j];
}
}
d=n1+n2;
for(int i=1;i<d;++i)
{
if(c[i]>9)
{
c[i+1]=c[i+1]+c[i]/10;
c[i]=c[i]%10;
}
}
while(c[d]==0&&d>1)
{
d--;
}
for(int i=d;i>=1;--i)
{
cout<<c[i];
}
return 0;
}
点击查看高精乘(单精*高精)
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string.h>
using namespace std;
struct bignum
{ int len,num[11111]; }a,b,c;
void num(string s)
{
reverse(s.begin(),s.end());
for(int i=0;i<s.size();i++)
{
a.num[i+1]=s[i]-'0';
}
a.len=s.size();
}
void cheng(int b)
{
int l=a.len;
memset(c.num,0,sizeof(c.num));
if(b==0)
{
c.len=1;
return;
}
for(int i=1;i<=l;i++)
{
c.num[i]+=(b*a.num[i]);
if(c.num[i]>=10)
{
c.num[i+1]=c.num[i]/10;
c.num[i]%=10;
}
}
while(c.num[l]!=0)
{
c.num[l+1]+=c.num[l]/10;
c.num[l++]%=10;
}
c.len=l-1;//c是从0开始
for(int i=c.len;i>0;i--)
{
printf("%d",c.num[i]);
}
}
int main()
{
string s;
int k;
cin>>s>>k;
num(s);
cheng(k);
return 0;
}
点击查看高精除
#include<bits/stdc++.h>
using namespace std;
int main(){
int e[11111]={0},b,c,d[11111]={0},f=0;
char a[11111]="0";
cin>>a;
c=strlen(a);
scanf("%d",&b);
for(int i=0;i<c;i++){
e[i]=a[i]-'0';
}for(int j=0;j<c;j++){
d[j]=e[j]/b;
e[j+1]=e[j]%b*10+e[j+1];
}for(int k=0;k<c;k++){
if(d[k]==0&&f==0){
continue;
}else{
printf("%d",d[k]);
}
if(d[k]!=0){
f=1;
}
}
return 0;
}