解题思路:
试商估算精确法
注意事项:注意要做减法的位置要对齐,冗余零要设置,大整数比较大小要弄明白位置

参考代码:

#include<stdio.h>

#include<string.h>

void shijinzhi(int *a,int k)//十进制函数,乘法中使用

{

if(a[k]>9)

{

a[k+1]+=a[k]/10;

a[k]=a[k]%10;

shijinzhi(a,k+1);

}

}

void cheng(int *a,int k,int len)//简易大整数乘法

{

for(int i=0;i<len;i++)

{

a[i]*=k;

}

for(int i=0;i<len;i++)

{

shijinzhi(a,i);

}

}

void diandao(int *a,int len)//颠倒数组

{

int temp;

for(int i=0,j=len;i<j;i++,j--)

{

temp=a[i];

a[i]=a[j];

a[j]=temp;

}

}

void jian(int *a,int k)//借位减法

{

int j=k;

if(a[j]<0)

{

a[j]=9;

j--;

a[j]--;

jian(a,j);

}

}

int find(int *a,int k)//寻找首位有效数字

{

int flag=k;

for(int i=0;i<=k;i++)

{

if(a[i]>0)

{

flag=i;

break;

}

}

return flag;

}

int compare(int *a,int *b,int j,int k)//大整数比较大小

{

for(int i=j-k,p=0;i<j;i++,p++)//找到需要比的第一位

{

if(a[i]>b[p])return 1;//因为是从高位比较到低位,所以可直接返回值

else if(a[i]<b[p])return -1;

}

return 0;//如果比到最后,那肯定是都一样大了

int main()

{

int a[305]={0},b[305]={0},c[305]={0},d[305]={0};//设置冗余零

char stra[300],strb[300];

scanf("%s%s",stra,strb);

int la=strlen(stra),lb=strlen(strb);

if(la>lb)

    {

        for(int i=0;i<la;i++)

        {

            a[i]=stra[i]-'0';

        }

        for(int i=0;i<lb;i++)

        {

            b[i]=strb[i]-'0';

        }

    }

    else if(la<lb)//特殊情况,数组a小于数组b

    {

        printf("0\n");

        printf("%s",stra);

        return 0;

    }

    else

    {

        if(strcmp(stra,strb)>=0)

        {

            for(int i=0;i<la;i++)

        {

            a[i]=stra[i]-'0';

        }

        for(int i=0;i<lb;i++)

        {

            b[i]=strb[i]-'0';

        }

        }

        else

        {

        printf("0\n");

        printf("%s",stra);

        return 0;

        }

    }

for(int i=lb-1,j=0;i<la;i++,j++)//除法初始位置是lb,但要注意数组中要减一

{

int h;

if(j==0)//首位特殊处理

{

h=(a[0]*10+a[1])/(b[0]*10+b[1]);

//这样的话试商比较准确,else分支同理

//因为设置了冗余零,不用担心程序崩溃,也不会影响试商

if(h==0)continue;

//特殊情况,最大的位置上都不够除,直接进入下一次循环

}

else 

{

h=(a[j-1]*100+a[j]*10+a[j+1])/(b[0]*10+b[1]);

if(h==0)continue;//与上同理

}

c[lb]=0;//重置特殊位置冗余零

for(int k=0;k<lb;k++)//把数组b存到临时数组c中

{

c[k]=b[k];

}

diandao(c,lb-1);//颠倒数组c,准备做乘法

cheng(c,h,lb);

int len;

if(j==0)

{

len=lb-1;

//特殊情况处理,因为我的compare函数的比较逻辑中如果j==0时会越界崩溃,且此时需要比的位次就是从j开始

}

else

{

len=lb;

}

diandao(c,len);//继续颠倒数组,有冗余零不用担心

int flag=compare(a,c,i,len);

//从被除最高位前一位比较,因为前一位可能会有剩余的数

//此时冗余零不会影响比较,而且c数组乘完可能会多一位

while(flag<0)//如果不够除就把商减一再比较

{

h--;

c[lb]=0;

for(int k=0;k<lb;k++)

{

c[k]=b[k];

}

diandao(c,lb-1);

cheng(c,h,lb);

diandao(c,len);

flag=compare(a,c,i,len);

}

diandao(c,len);

diandao(c,lb);//统一减法位置

for(int o=1,p=i-lb+1;p<=i;p++,o++)

{

if(a[p]>=c[o])

{

a[p]-=c[o];

}

else

{

a[p]=a[p]+10-c[o];

a[p-1]--;

jian(a,p-1);

}

}

if(j>0)//如果c数组有进位就减,就算没有进位,此时冗余零也不影响

{

a[j-1]-=c[0];

}

d[j]=h;//记录到d数组

}

int key=find(d,la);//找到有效位置,去除前导零

for(int i=key;i<la-lb+1;i++)

{

printf("%d",d[i]);

}

printf("\n");

key=find(a,la);

for(int i=key;i<la;i++)

{

printf("%d",a[i]);

}

if(key==la)//特殊情况,余数为零

{

printf("0");

}

return 0;

}


点赞(0)
 

0.0分

0 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论