信息学奥赛一本通:1308:【例1.5】高精除
1308:【例1.5】高精除
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 15501 通过数: 7597
【题目描述】
高精除以高精,求它们的商和余数。
【输入】
输入两个低于300位的正整数。
【输出】
输出商和余数。
【输入样例】
1231312318457577687897987642324567864324567876543245671425346756786867867867
1231312318767141738178325678412414124141425346756786867867867
【输出样例】
999999999748590
179780909068307566598992807564736854549985603543237528310337
用了三天时间完成
用的字符处理,如果用整形数组,在做除时,大约一个道理
#include<iostream>
#include<cmath>
#include<cstring>
char a[305],b[305],c[3005],sum[305];
int dashuchu(char p[],char q[],int n,int i)//大数除法,pq没用,就是ab
{
int x,y=0,k;
do {
for(x=n-1;x>=0;x--)//从个位开始计算
{
if(a[x]<b[x]){//先比较大小,要够减的
a[x-1]--;//高位减1,低位 加10
a[x]+=10;
}
a[x]=a[x]-b[x]+'0';//减出来
} y++;//就 是商1了
}while(strcmp(a,b)>0||strcmp(a,b)==0);//当a不小于b时,继续做
for(x=0,k=i;x<n;x++,k++)
c[k]=a[x];// 做完了除(就是减),a把余下的归还c的相应数位
return y;//返还减的次数(即商)
}
using namespace std;
int main()
{
scanf("%s\n %s",c,b);//被除数和除数
int m,n,j,i,t;
n=strlen(b);// 字串的长度 ,除数的长度,下面用的较多
m=strlen(c);
for(i=0;i<=m-n;i++)//商的长度最大是m-n+1,置0字符
sum[i]='0';
for(i=0;i<=m-n;i++){//开始计算,从0位即高位开始,商位数是m-n+1或是m-n
//从这再开始计算
for(j=0,t=i;j<n;j++,t++)//从c被除数中取和除数相同位数的字串
//到a中,从0位开始
a[j]=c[t];
a[j]='\0';//最后加字串结束符号
if(strcmp(a,b)>=0)//如果能除,有商
sum[i]+=(char)dashuchu(a,b,n,i); //相应的商位上,放上数
//a是被除数,最后是余下的;b是除数,不变;n除数长度,i第几位了
{ //a不大于b时
c[i+1]=(c[i]-'0')*10+c[i+1];//剩下的被除数高位*10加在低一个的位上
c[i]='\0';//原来的位上放字符0
}//这样求出商的一位,再从上面的循环再开始
}
i=0;
while(sum[i]=='0')i++;//erase the zero.
for(;i<m-n+1;i++)//不能大于商的长度
putchar(sum[i]);
printf("\n");
i=0;
while(a[i]=='0')i++;//找余数,去0
if(i==n)//全是0
printf("0");
else
for(;i<n;i++)
putchar(a[i]);//还剩下的
return 0;
}