模拟除法:指的是超过了int,用除法运算符不能解决,但又没达到大数相除的范围的除法。这类除法一般商用string存起来。即:除数和商可以用long long存,被除数用string存。
这类题目很有可能以乘法的形式给出,需要求一个超过了long long 范围的积,但恰好因数有办法得到。
在一般的比赛中,模拟除法比大数相除应用的还要广泛。
具体算法:
模拟竖式:我们想要得到最高位的商,并将被除数缩小,/ 运算符和 % 可以组合使用
//模拟除法的关键
ans += (a / b + ' 0'); //a->被除数 b->除数
a %= b;
具体的细节请看代码:
int main()
{
long long a = 0; //被除数
long long b = 0;
string ans;
cin >> a >> b;
int flag = 1; //判断是否加了小数点
int count = 10; //限定位数,不是所有数都能整除
while (a != 0 && count != 0)
{
if (a < b) //小数点只能加一次
{
a *= 10;
if(flag == 1)
ans += '.';
flag--;
}
ans += (a / b + ' 0');
count--;
a %= b;
}
cout << ans;
return 0;
}
一看即明,不再赘述。
上题目:(题目属于内部链接,本文只能透露题目内容)
弄懂了上面的代码,此题处理起来也不难
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int main()
{
long long n = 0;
cin >> n;
string ans;
long long count = 1;
long long k = 1;
int flag = 0; //0表示还没有补0, 1表示补了0
while (k != 0)
{
if (k >= n) //被除数大于除数,先除了再说
{
ans += (k / n + '0');
k %= n;
flag = 0;
}
else //除到一半发现被除数没有了,继续扩充被除数
{
// 特判:如果已经补了1还是不够除,就要先商一个0
if(flag == 1)
{
ans += '0';
// 注意这里不能将flag变为0,因为可能补了好多个1都不够除,例如 1 / 123456889
}
k = k * 10 + 1;
count++;
flag = 1;
continue; // 回去再除
}
}
for (int i = 0; i < ans.size(); i++)
{
if (ans[i] != '0') //去除ans的前导0
{
cout << ans[i];
}
}
cout << endl << count;
return 0;
}
有不懂的小伙伴可以评论或私信问我~
希望和诸君共勉