大數乘除

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,階乘的時候,每個數組都與下一位要乘的數直接相乘,溢出的值向前面進位,按照這種方式,可以實現任何進制。

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