藍橋杯決賽試題:求1到n的最小公倍數

題目:ios

爲何1小時有60分鐘,而不是100分鐘呢?這是歷史上的習慣致使。
但也並不是純粹的偶然:60是個優秀的數字,它的因子比較多。
事實上,它是1至6的每一個數字的倍數。即1,2,3,4,5,6都是能夠除盡60。
1 2 3 4 5 6算法

咱們但願尋找到能除盡1至n的的每一個數字的最小整數。數組

不要小看這個數字,它可能十分大,好比n=100, 則該數爲:
6972 0375 2297 1247 7164 5338 0893 5312 3035 5680 0函數

請編寫程序,實現對用戶輸入的 n (n<100)求出1~n的最小公倍數。spa

例如:
用戶輸入:
6
程序輸出:
60code

用戶輸入:
10
程序輸出:
2520orm

題目分析:ci

題目求的是前n個數的最小公倍數,若是咱們求出了前n-1個數的最小公倍數,咱們怎麼來求前n個數的最小公倍數?咱們假設前n-1個數的最小公倍數是a,第n個數是b,it

那麼前n個數的最小公倍數是a*b/gcd(a,b)(gcd表示歐幾里德算法,用於求兩個數的最大公約數),好,如今問題的關鍵咱們分析清楚了,但有個問題啊,就正如題目說的,數據可能很是大,也就是上面分析的公式中的a可能很是大,這時,咱們簡單的類型是存儲不下這麼大的數據,針對這種狀況,咱們就只能用數組去進行相應的存儲(大數操做)。到了這裏,思路大概就分析清楚了,咱們再來觀察一下這個公式,a*b/gcd(a,b),若是咱們順序去求這個公式的話,咱們要編寫的大數函數就有三個(大數相乘(a*b)、大數相除(a*b)/gcd(a,b)、大數求模gcd(a,b)),咱們再來仔細看下這個公式gcd(a,b)表示a,b的最大公因數,那麼b/gcd(a,b)呢?b是小於100的,而gcd(a,b)又是a,b的最大公約數,b/gcd(a,b)的結果是不會超過100的,因此咱們能夠把b/gcd(a,b)當作是一個總體,這樣的話,咱們就只用編寫兩個關於大數的函數(大數相乘、大數求模),好了,全部的狀況都分析清楚了,那就貼代碼了.io

代碼:

#include<iostream>

using namespace std;

#define MAXN 100000

char res[MAXN] = {'\0'};

void multi(char* ch,int num)

{

int i,high=0,temp;

for(i=0;ch[i];++i)

{

temp = num*(ch[i]-48)+high;

ch[i] = temp%10 + '0' ;

high = temp /10;

}

//針對進位還有剩餘的狀況

while(high)

{

ch[i++] = high%10+48;

high /=10;

}

}

int gcd(int a,int b)

{

return b==0 ? a : gcd(b,a%b);

}

int mod(char* ch,int b)

{

int left=0,i;

for(i=-1;ch[i+1]!='\0';++i);

for(;i>=0;--i)

{

left = left*10+ch[i]-48;

left %=b;

}

return left==0 ? b : gcd(b,left);

}

void solve(int n)

{

res[0]='1';

for(int i=2;i!=n+1;++i)

{

int temp = mod(res,i);

multi(res,i/temp);

}

}

void print(char* ch)

{

int i;

for(i=-1;ch[i+1];++i);

for(;i>=0;--i)

{

cout << ch[i] ;

}

}

int main()

{

int n;

cin >> n;

solve(n);

print(res);

return 0;

}
相關文章
相關標籤/搜索