高精度计算算法精髓:暴力出奇迹的竖式计算和字符串处理。
以下是一些模板题,还是要靠您的具体实践去运用高精算法。
高精加减法的思想都是先倒序储存数字字符串,然后按位做加减法运算,对应的进位或借位,最后输出。代码如下。
高精加法
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
string s;
int jia[520],n,m;
int main()
{
cin >> s;
n=(int)s.length();
for(int i=0;i<n;i++) jia[i]=s[s.length()-1-i]-'0';//储存
cin >> s;
m=(int)s.length();
for(int i=0;i<m;i++) jia[i]+=s[s.length()-1-i]-'0';//加
if(n >= m)
{
for(int i=0;i<n;i++)
if(jia[i] >= 10) {jia[i+1]+=jia[i]/10; jia[i]=jia[i]%10;}//进位
int p;
for(p=500;p>=0;p--) if(jia[p] > 0) break;
if(p < 0) {printf("0"); return 0;}//输出
for(;p>=0;p--) printf("%d",jia[p]);
}
else//以下同上
{
for(int i=0;i<m;i++)
if(jia[i] >= 10) {jia[i+1]+=jia[i]/10; jia[i]=jia[i]%10;}
int p;
for(p=500;p>=0;p--) if(jia[p] > 0) break;
if(p < 0) {printf("0"); return 0;}
for(;p>=0;p--) printf("%d",jia[p]);
}
return 0;
}
高精减法
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
string s1,s2;
int jian[10010],n,m;
int main()
{
cin >> s1 >> s2;//输入
n=s1.length();m=s2.length();
if(s1 == s2) {printf("0"); return 0;}
if(m > n || (m == n && s1 < s2))
{
printf("-");
for(int i=0;i<m;i++) jian[i]=s2[m-i-1]-'0';//存储
for(int i=0;i<n;i++)
{
if(jian[i] < s1[n-i-1]-'0') {jian[i]+=10; jian[i+1]--;}
jian[i]-=s1[n-i-1]-'0';//减
}
for(int i=n;i<m;i++) if(jian[i] < 0) {jian[i]+=10; jian[i+1]--;}//处理
int p;
for(p=m-1;jian[p]>0;p--)
for(;p>=0;p--) printf("%d",jian[p]);//输出
}
else//以下同上
{
for(int i=0;i<n;i++) jian[i]=s1[n-i-1]-'0';
for(int i=0;i<m;i++)
{
if(jian[i] < s2[m-i-1]-'0') {jian[i]+=10; jian[i+1]--;}
jian[i]-=s2[m-i-1]-'0';
}
for(int i=m;i<n;i++) if(jian[i] < 0) {jian[i]+=10; jian[i+1]--;}
int p;
for(p=n-1;jian[p]>0;p--)
for(;p>=0;p--) printf("%d",jian[p]);
}
return 0;
}
高精乘法思想:找规律(见代码)。
窝的代码这么通俗易懂应该能看懂吧(逃
高精乘法
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
string a,b;
int ji[60010],lena,lenb,len;
bool pd[60010];
int main()
{
cin >> a >> b;
if(a[0] == '0' || b[0] == '0') {printf("0"); return 0;}
lena=a.length();lenb=b.length();len=lena+lenb;
for(int i=0;i<lena;i++)//存储
for(int j=0;j<lenb;j++) {ji[i+j+1]+=(a[i]-'0')*(b[j]-'0'); pd[i+j+1]=true;}
for(;ji[len] == 0 && pd[len] == false;len--)
for(int i=len;i>0;i--) if(ji[i] >= 10) {ji[i-1]+=ji[i]/10; ji[i]=ji[i]%10;}//进位
if(ji[0]) printf("%d",ji[0]);
for(int i=1;i<=len;i++) printf("%d",ji[i]);//输出
return 0;
}
上面的代码能暴力碾标算。很神奇。
高精除法
高精除以低精:(余数*10+下一位)/除数。
#include <cstdio>
#include <iostream>
#include <string>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
string a;
int b,jin,n,s[5010];
int main()
{
cin >> a;
if(a[0] == '0') {printf("0"); return 0;}
scanf("%d",&b);
n=a.length();
for(int i=0;i<n;i++) {s[i]=(a[i]-'0'+jin*10)/b; jin=(a[i]-'0'+jin*10)%b;}//除法
int i;
for(i=0;!s[i] && i<n;i++)
if(i == n) {printf("0"); return 0;}
for(;i<n;i++) printf("%d",s[i]);//输出
return 0;
}
高精除以高精
这个窝不会
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
string n,m;
int a[1000010],b[1000010],c[1000010],t[1000010];
int pd(int aa[],int bb[])
{
if(aa[0] > bb[0]) return 1;
else if(bb[0] > aa[0]) return -1;
for(int i=aa[0];i>0;i--)
if(aa[i] > bb[i]) return 1;
else if(bb[i] > aa[i]) return -1;
return 0;
}
void ncopy(int aa[],int bb[],int len)
{
for(int i=1;i<=aa[0];i++) bb[i+len-1]=aa[i];
bb[0]=aa[0]+len-1;
}
int main()
{
cin >> n >> m;
a[0]=n.length();b[0]=m.length();c[0]=a[0]-b[0]+1;
for(int i=1;i<=a[0];i++) a[i]=n[a[0]-i]-'0';
for(int i=1;i<=b[0];i++) b[i]=m[b[0]-i]-'0';
for(int i=c[0];i>0;i--)
{
memset(t,0,sizeof(t));
ncopy(b,t,i);
while(pd(a,t) >= 0)
{
c[i]++;
if(!pd(a,t)) {a[0]=0; continue;}
for(int j=1;j<=a[0];j++)
{
if(a[j] < t[j]) {a[j+1]--; a[j]+=10;}
a[j]-=t[j];
}
while(a[0] > 0 && !a[a[0]]) a[0]--;
}
}
while(c[0] > 0 && !c[c[0]]) c[0]--;
if(!c[0]) printf("0");
else for(int i=c[0];i>0;i--) printf("%d",c[i]);
return 0;
}
前方高能!!!
高精模板集合题
P1932 A+B A-B A*B A/B A%B Problem
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
string sa,sb;
int jia[10010],jian[10010],ji[100000010],n,m;
bool pdd[100000010];
void pluss(string a1,string b1)
{
n=a1.length();m=b1.length();
for(int i=0;i<n;i++) jia[i]=a1[a1.length()-1-i]-'0';
for(int i=0;i<m;i++) jia[i]+=b1[b1.length()-1-i]-'0';
if(n >= m)
{
for(int i=0;i<n;i++)
if(jia[i] >= 10) {jia[i+1]+=jia[i]/10; jia[i]=jia[i]%10;}
int p;
for(p=n;p>=0;p--) if(jia[p] > 0) break;
if(p < 0) printf("0");
else for(;p>=0;p--) printf("%d",jia[p]);
}
else
{
for(int i=0;i<m;i++)
if(jia[i] >= 10) {jia[i+1]+=jia[i]/10; jia[i]=jia[i]%10;}
int p;
for(p=m;p>=0;p--) if(jia[p] > 0) break;
if(p < 0) printf("0");
else for(;p>=0;p--) printf("%d",jia[p]);
}
puts("");
return ;
}
void jiand(string a2,string b2)
{
n=a2.length();m=b2.length();
if(a2 == b2) printf("0");
else
if(m > n || (m == n && a2 < b2))
{
printf("-");
for(int i=0;i<m;i++) jian[i]=b2[m-i-1]-'0';
for(int i=0;i<n;i++)
{
if(jian[i] < a2[n-i-1]-'0') {jian[i]+=10; jian[i+1]--;}
jian[i]-=a2[n-i-1]-'0';
}
for(int i=n;i<m;i++) if(jian[i] < 0) {jian[i]+=10; jian[i+1]--;}
int p;
for(p=m;;p--) if(jian[p] > 0) break;
for(;p>=0;p--) printf("%d",jian[p]);
}
else
{
for(int i=0;i<n;i++) jian[i]=a2[n-i-1]-'0';
for(int i=0;i<m;i++)
{
if(jian[i] < b2[m-i-1]-'0') {jian[i]+=10; jian[i+1]--;}
jian[i]-=b2[m-i-1]-'0';
}
for(int i=m;i<n;i++) if(jian[i] < 0) {jian[i]+=10; jian[i+1]--;}
int p;
for(p=n;;p--) if(jian[p] > 0) break;
for(;p>=0;p--) printf("%d",jian[p]);
}
puts("");
return ;
}
void cheng(string a3,string b3)
{
int len;
if(a3[0] == '0' || b3[0] == '0') printf("0");
else
{
n=a3.length();m=b3.length();len=n+m;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++) {ji[i+j+1]+=(a3[i]-'0')*(b3[j]-'0'); pdd[i+j+1]=true;}
for(;ji[len] == 0 && pdd[len] == false;len--)
for(int i=len;i>0;i--) if(ji[i] >= 10) {ji[i-1]+=ji[i]/10; ji[i]=ji[i]%10;}
if(ji[0]) printf("%d",ji[0]);
for(int i=1;i<=len;i++) printf("%d",ji[i]);
}
puts("");
return ;
}
int pd(int aa[],int bb[])
{
if(aa[0] > bb[0]) return 1;
else if(bb[0] > aa[0]) return -1;
for(int i=aa[0];i>0;i--)
if(aa[i] > bb[i]) return 1;
else if(bb[i] > aa[i]) return -1;
return 0;
}
void ncopy(int aa[],int bb[],int len)
{
for(int i=1;i<=aa[0];i++) bb[i+len-1]=aa[i];
bb[0]=aa[0]+len-1;
return ;
}
void chu(string a4,string b4)
{
int a[10010],b[10010],c[10010],t[10010];
a[0]=a4.length();b[0]=b4.length();c[0]=a[0]-b[0]+1;
for(int i=1;i<=a[0];i++) a[i]=a4[a[0]-i]-'0';
for(int i=1;i<=b[0];i++) b[i]=b4[b[0]-i]-'0';
for(int i=c[0];i>0;i--)
{
memset(t,0,sizeof(t));
ncopy(b,t,i);
while(pd(a,t) >= 0)
{
c[i]++;
if(!pd(a,t)) {a[0]=0; continue;}
for(int j=1;j<=a[0];j++)
{
if(a[j] < t[j]) {a[j+1]--; a[j]+=10;}
a[j]-=t[j];
}
while(a[0] > 0 && !a[a[0]]) a[0]--;
}
}
while(c[0] > 0 && !c[c[0]]) c[0]--;
if(c[0] <= 0) printf("0");
else for(int i=c[0];i>0;i--) printf("%d",c[i]);
puts("");
if(!a[0]) printf("0");
else for(int i=a[0];i>0;i--) printf("%d",a[i]);
return ;
}
int main()
{
cin >> sa >> sb;
pluss(sa,sb); jiand(sa,sb); cheng(sa,sb); chu(sa,sb);
return 0;
}
麻烦问一下,橙书是啥书啊?