本人大一新生一枚 寒假训练时遇到高精度这题一开始用滚动减法 T了十发 在其他人的博客上看到说要把除数扩大才行 但是其他大神写的代码实在看的是云里雾里 自己就用自己理解的方式写了一遍 正好有写个博客的打算 因为我的目标是星辰大海嘛 总得为后人留下点什么 代码排版有点丑 第一次写见谅。。。。
核心思想
只用单纯的减法去模拟除法肯定是会T的比如3000000/1
那么我们就需要将除数扩大到能除的极限就可以最大限度的优化
那么我们就需要将除数扩大到能除的极限就可以最大限度的优化
比如上述例子我们可以将 1 扩大到 1000000 就只需要减3次就可达到目的
再比如 12345/45:
i=
3
12345 <
45000 可以减
0个 shang[3]=
0 减后A:
12345
i=2 12345 < 4500 可以减 2个 shang[ 2]= 2 减后A: 3345
i= 1 3345 < 450 可以减 7个 shang[ 1]= 7 减后A: 195
i= 0 195 < 45 可以减 4个 shang[ 0]= 4 减后A: 15
i=2 12345 < 4500 可以减 2个 shang[ 2]= 2 减后A: 3345
i= 1 3345 < 450 可以减 7个 shang[ 1]= 7 减后A: 195
i= 0 195 < 45 可以减 4个 shang[ 0]= 4 减后A: 15
总次数等于 0*10^3+2*10^2+7*10^1+4*10^0=274
仅仅减了2+7+4=13次,而非274次
例子转自 https://www.cnblogs.com/lfyzoi/p/6737761.html
#include<stdio.h>
#include<string.h>
char n[1000],m[1000];
int a[1000],b[1000];
int s[1000];
int lena,lenb;
void add(int t)
{
int i,r=0,p;
s[t]+=1; //扩大了多少倍的除数 就增加10的多少次方 不要用pow 因为int存不下!
for(i=0;i<=lena;i++)
{
p=s[i]+r;
r=p/10;
s[i]=p%10;
}
}
int cp()
{
int i;
for(i=lena;i>=0;i--)
{
if(a[i]>b[i]) //判断除数是否小于被除数
return 1;
else if(a[i]<b[i])
return 2;
}
return 0; //一定要有这个!如果除数等于被除数会出错!
}
int main()
{
int i,j,z;
while(scanf("%s%s",n,m)!=EOF)
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(s,0,sizeof(s));
lena=strlen(n);
lenb=strlen(m);
for(i=lena-1,j=0;i>=0;i--,j++) //倒着输入进去方便减法
a[j]=n[i]-'0';
for(i=lenb-1,j=lena-lenb;i>=0;i--,j++) //很重要的一步 将除数扩大到能除的极限
b[j]=m[i]-'0';
if(strcmp(n,m)==0) //合理排除 除数相同的情况
{ //注意除数为0的情况
if(n==0)
printf("0");
else
printf("1\n");
printf("0\n");
continue;
}
else if(strlen(m)>strlen(n)||strcmp(n,m)<0&&strlen(n)==strlen(m)) //合理排除被除数小于除数的情况
{
printf("0\n");
for(i=lena;i>=0;i--)
if(a[i])
break; //注意要输出商
if(i==-1)
printf("0");
else
for(;i>=0;i--)
printf("%d",a[i]);
printf("\n");
continue;
}
else
{
for(i=lena-lenb;i>=0;i--) //因为一开始除数后添加了 lena-lenb的0 所以之后需要一个一个消去添加的0
{
while(1)
{
if(cp()==2) //检测除数是否小于被除数
break;
add(i); //除数后面添加了多少个0 就加上10的多少次方
for(z=0;z<lena;z++) //减法部分
{
if(a[z]<b[z])
{
a[z]+=10;
a[z+1]--;
}
a[z]-=b[z];
}
}
for(j=0;j<lena;j++) //所有数向前移一位 相当于/10
b[j]=b[j+1];
}
for(i=lena;i>=0;i--) //输出商
if(s[i])
break;
for(;i>=0;i--)
printf("%d",s[i]);
printf("\n");
for(i=lena;i>=0;i--) //输出余数 注意余数为0也要输出
if(a[i])
break;
if(i==-1)
printf("0");
else
for(;i>=0;i--)
printf("%d",a[i]);
printf("\n");
}
}
return 0;
}
写博客只为给自己的寒假训练一个交代 也证明一下自己还是有点东西的
欢迎和我交流QQ727518497!