0
点赞
收藏
分享

微信扫一扫

FNOI_TEST_1 b(高精度除法)


​​http://www.elijahqi.win/archives/597​​​
2.整除(b.cpp/c/pas)
【问题描述】 给出两个正整数 n、m,求 n 除以 m 的商和余数。 【输入数据】 第一行一个正整数 n。 第二行一个正整数 m。 【输出数据】 第一行一个正整数表示 n 除以 m 的商。 第二行一个正整数表示 n 除以 m 的余数。 【输入输出样例 1】 b.in b.out 97 15 6 7 【输入输出样例 2】 b.in b.out 919308219 1254 733100 819 【输入输出样例 3】 b.in b.out 37016651297381047164 7 5288093042483006737 5 【输入输出样例 4】 b.in b.out 666666666666666666666666666666 233 2861230329041487839771101573 157 【数据规模和约定】 测试点编号 n m 1 <=100 <=9 2 <=10^7 <=1000 3 <=10^9 <=10000 4 <=10^100 <=9 5 <=1000 6 <=10^50 7 <=10^10000 <=9 8 <=1000 9 <=10^50 10 <=10^200 对于 100%的数据:1<=n<=10^10000,1<=m<=10^200,m<=n

大意就是求两个大整数相除 注意存在余数为0的情况

#include<cstdio>
#include<cstring>
#define N 11000
#define N1 220
int ans[N];
char n1[N],m1[N1];
int n[N],m[N1],nn,mm,ans1,cnt,st=1;
inline void subtract(int st1,int ed){
int tmp=0;
for (int i=1;i<=mm;++i){
n[ed-i+1]+=tmp;
if (n[ed-i+1]<m[mm-i+1]) tmp=-1,n[ed-i+1]+=10;else tmp=0;
n[ed-i+1]-=m[mm-i+1];
}
if (ed-st1+1>mm) n[st1]+=tmp;
while (n[st]==0) st++;

}
inline bool judge(int st1,int ed){
int ll=ed-st1+1; if (ll>mm) return true;else if(ll<mm) return false;
for (int i=1;i<=mm;++i) {
if(n[st1+i-1]<m[i]) return false;
if(n[st1+i-1]>m[i]) return true;
}

}
int main(){
freopen("b.in","r",stdin);
freopen("b.out","w",stdout);
scanf("%s",n1+1);
scanf("%s",m1+1);
nn=strlen(n1+1);mm=strlen(m1+1);
for (int i=1;i<=nn;++i) n[i]=n1[i]-'0';
for (int i=1;i<=mm;++i) m[i]=m1[i]-'0';
//for (int i=1;i<=nn;++i) printf("%d",n[i]);printf("\n");
//for (int i=1;i<=mm;++i) printf("%d",m[i]);printf("\n");
for (int i=mm;i<=nn;++i){
ans1=0;
while (judge(st,i)){
ans1++;
subtract(st,i);
//for (int i=1;i<=nn;++i) printf("%d",n[i]);printf("\n");
// for (int i=1;i<=mm;++i) printf("%d",m[i]);printf("\n");
}
ans[++cnt]=ans1;

}
int num=1;while (ans[num]==0) num++;
for (int i=num;i<=cnt;++i) printf("%d",ans[i]);printf("\n");
if(st>nn) printf("0\n");
for (int i=st;i<=nn;++i) printf("%d",n[i]);

return 0;
}

一起看下官方题解吧

2.整除(b) 【30 分】 把 n 和 m 作为 int 读入,直接计算答案。时间复杂度 O(1)。 【70 分】 m<=10000,考虑从高位到低位逐位确定商,模拟竖式除法,每一位都做一个 int 以内的除法,求出商以后自然得到余数。设 len1 为 n 的位数, len2 为 m 的位数, 时间复杂度 O(len1)。 【80 分】 同样考虑从高位到低位逐位确定商,模拟竖式除法,但由于 m 超过了 longlong, 无法直接做除法。由于商的每一位都<=9,用减法模拟除法即可。实现比较两个 高精度数的大小和高精度减法即可。由于比大小时 n 的位数为 O(len1),故时间 复杂度 O(9*len1^2),无法通过 9、10 测试点。 【100 分】 注意到减法模拟除法时 n 的前面很多位都是 0,事实上只会涉及到当前的 n 的后 len2+1位,故比大小和高精度减法复杂度均为O(len2),时间复杂度O(9*len1*len2)。

举报

相关推荐

0 条评论