模拟除法详解

模拟除法:指的是超过了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;
}

有不懂的小伙伴可以评论或私信问我~

希望和诸君共勉

猜你喜欢

转载自blog.csdn.net/qq_61567032/article/details/124625057