高精度除法

搞了一下午,弄懂了一个高精度除法

https://www.bnuoj.com/v3/problem_show.php?pid=52155

虽然按题的要求超内存了,,,但,还算是收货吧

坑点:关系运算法的优先级比赋值运算符高,少了一个括号,调试了半个小时

还有一个本来是<=结果弄成了<,有调试了半个小时

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>

using namespace std;
const int maxn = 1e7 + 5;
string str1;//除数 
string str2 = "73";
string str3 = "137";
int len1;
int len2 = 2;
int len3 = 3;
int fm[maxn], num[maxn];
int SubStract(int *fm, int *num, int len1, int ll)
{
//说明比他小
	if (len1<ll)
		return -1;
	if (len1 == ll)
	{
//正序,意思是从高位开始比,比较两个的大小
		for (int i = len1 - 1; i >= 0; i--)
		{
//有一位大就肯定大
			if (fm[i]>num[i])
				break;
//有一位小就肯定小
			else if (fm[i]<num[i])
				return -1;
		}
	}
//就是这个地方,i<=len1-1,少了一个小于号,导致当fm和73相等的时候出错
//模拟减法,从低位开始,不够向上一位借1
	for (int i = 0; i<=len1 - 1; i++)
	{
		fm[i] -= num[i];
		if (fm[i]<0)
		{
			fm[i] += 10;
			fm[i + 1]--;
		}
	}
	/*for (int i = len1-1; i >=0; i--)
	{
		printf("%d", fm[i]);
	}
	printf("\n");*/
//返回现在被除数的位数
	for (int i = len1 - 1; i >= 0; i--)
	{
		if (fm[i])
			return (i + 1);
	}
//说明两个数相等
	return 0;
}
//用的是指针,每次操作之后fm都会更新
int judge(int *fm, string s)
{
	int ll = s.length();
	int ntimes = len1 - ll;
//把被除数弄成和除数一样长,还是倒序
	for (int i = 0; i<ntimes; i++)
	{
		num[i] = 0;
	}
	int cnt = 1;
//又坑了半小时..处理的第一个数是被除数的最后一位...
	for (int i = ntimes; i<len1; i++)
	{
		num[i] = s[ll - cnt++] - '0';
	}
	ll = len1;
	int ntemp;
	for (int k = 0; k <= ntimes; k++)
	{
		//错因:关系运算符的优先级比赋值运算符高,一开始没写括号,调试了半小时
//当ntemp小于0时,被除数已经小于除数,所以除数去一个0
		while ((ntemp = SubStract(fm, num + k, len1, ll - k)) >= 0)
		{
			len1 = ntemp;
		}
	}
	return len1;
}
int main()
{
	while (cin >> str1)
	{
		len1 = str1.length();
//倒向处理,因为模拟减的时候是从个位开始,个位是在字符串的最后一位,所以颠倒了
		for (int i = len1 - 1; i >= 0; i--)
		{
			fm[len1 - 1 - i] = str1[i] - '0';
		}
//如果被除数比除数小,只能是0才能
		if (len1<len2 || len1<len3)
		{
			if (str1 == "0")
			{
				printf("YES\n");
			}
			else
			{
				printf("NO\n");
			}
			continue;
		}
//看是不是能整除
		int result1 = judge(fm, str2);
		if (result1 != 0)
		{
			printf("NO\n");
			continue;
		}
		len1 = str1.length();
		for (int i = len1 - 1; i >= 0; i--)
		{
			fm[len1 - 1 - i] = str1[i] - '0';
		}
		int result2 = judge(fm, str3);
		if (result2 != 0)
		{
			printf("NO\n");
		}
		else
		{
			printf("YES\n");
		}
	}
	return 0;
}

另外还不会调试不会直接打印出来,还单步调试......

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值