大数乘除

L1-046 整除光棍 (20 分)

这里所谓的“光棍”,并不是指单身汪啦~ 说的是全部由1组成的数字,比如1、11、111、1111等。传说任何一个光棍都能被一个不以5结尾的奇数整除。比如,111111就可以被13整除。 现在,你的程序要读入一个整数x,这个整数一定是奇数并且不以5结尾。然后,经过计算,输出两个数字:第一个数字s,表示x乘以s是一个光棍,第二个数字n是这个光棍的位数。这样的解当然不是唯一的,题目要求你输出最小的解。

提示:一个显然的办法是逐渐增加光棍的位数,直到可以整除x为止。但难点在于,s可能是个非常大的数 —— 比如,程序输入31,那么就输出3584229390681和15,因为31乘以3584229390681的结果是111111111111111,一共15个1。

输入格式:

输入在一行中给出一个不以5结尾的正奇数x(<1000)。

输出格式:

在一行中输出相应的最小的sn,其间以1个空格分隔。

输入样例:

31

输出样例:

3584229390681 15

这道题是比较典型的超过正常整数范围的题目,一般在大数处理中很常见,先解决这个问题,这里用到了模拟除法原则,由于被除数未知,但是他有规律可循,所以先找到大于x,且最接近x的光棍数字,比如输入的数字x为9,则第一个光棍数字选择11,然后模拟除法原则,

模拟除法

 

虽然写的丑,但还是很直观的,接下来看代码就很直观了,

#include<bit/stdc++.h>

using namespace std;

typedef unsigned long long ll;
int main() {
	ll N, big = 1, cnt = 1;;
	scanf_s("%lld", &N);
	while (big < N) {//先找到N附近的光棍
		big *= 10;
		big += 1;
		++cnt;
	}
	while (1) {//除法公式分解,可以用于大数除法
		printf_s("%lld", big / N);
		if (big % N == 0) {
			break;
		}
		else {
			big %= N;
			big *= 10;
			big += 1;
			++cnt;
		}
	}
	printf_s(" %lld", cnt);
	return 0;
}

这是一种解法。不过这道题用万进制的效果不好,

下面看一下万进制用于阶乘的例子,我们知道即使是64位的整数,其最大的整数也只能到18446744073709551615,在高位阶乘的时候远远不够,这时只能用其他方法来保存阶乘后得到的值,废话不多说,直接上代码

#include<iostream>
#include<iomanip>
using namespace std;

int main()
{
	void factorial(int n);  //阶乘函数

	int n;

	while (cin >> n)
		factorial(n);

	return 0;
}

void factorial(int n)
{//万进制
	int a[10001];//用于存储数值
	int places, carry, i, j;

	a[0] = 1;
	places = 0;   //当前数的总位数
	for (i = 1; i <= n; i++)
	{
		carry = 0;   //进位

		for (j = 0; j <= places; j++)
		{//先从低位(每十进制的四位为万进制的一位)开始计算,由低到高,按照乘法规则相乘,进位
			a[j] = a[j] * i + carry;//相乘,加上进位
			carry = a[j] / 10000;//求出进位(后面加到高位)
			a[j] %= 10000;//留下取余后的数字
		}

		if (carry > 0)  //如果一个数的总前一位大于一万,则向前进位
		{
			places++;//for循环后的进位是新增加的位
			a[places] = carry;
		}
	}

	/*
	  输出
	  最高位原样输出,
	  其他位小于1000的,高位补0
	*/
	cout << a[places];
	for (i = places - 1; i >= 0; i--)//从后面开始输出
		cout << setw(4) << setfill('0') << a[i];

	cout << endl;
}

用整数数组来保存输出值,每个数组元素的值得范围为0-999,阶乘的时候,每个数组都与下一位要乘的数直接相乘,溢出的值向前面进位,按照这种方式,可以实现任何进制。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章