2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
找出最小的能夠除盡1-20中間所有的數的正數。
這個題,我就是使用傳說中的筆算,算出來的O(∩_∩)O哈哈~
首先看下能夠除盡1-10中間所有的數 2520
然後分析下11-20中間所有的數
11, 12, 13, 14, 15 , 16 , 17 , 18 ,19, 20
第一步可以挑選出質數,質數肯定是不能分解的。那我們要找的數就是2520 * 11 * 13 * 17 * 19的倍數
第二步, 看下 12 = 2*6
14 = 2*7
15 = 3*5
16 = 2*2*2*2
18 = 2*3*3
20 = 2*5*2
也就是說新的數肯定不用考慮 14 15 了,因為2520裡面已經包含了這個因子, 剩下需要考慮16 18 20 這3個
第三部, 我們可以看下2520 肯定可以被9 整除,同時 它也是2的倍數,故排除18,同理20.剩下需要處理16.
第四步,用2520除以16就發現只餘下0.5,這樣可以乘以最小的因子,也就是2 就可以滿足了。
那樣那個數就是
2520 * 11 * 13 * 17 * 19 * 2
哈哈。下面給出如何用電腦程式來解決這個問題吧
先說下使用電腦解決的思想:(使用比較簡單的數組來解決)
找出能夠整除1-N中間所有數的最小數
- 找出1-N中間所有的素數,放入數列a[N]中,a[N]不足的部分使用1來填充。
- 求出所有素數相乘的積。然後對剩下1-N中除去素數剩下的數,進行一次快速的刪選。用這個乘積去%剩下的數種每個一個數,如果可以除盡,那剔除這個數。不能除盡保留。
- 對於保留的數,進行因素拆分,比如像16 = 2*2*2*2. 拆分的數對比那個素數數列a[N]。找出比如16裡面有的,a[N]裡面沒有的部分。比如16 裡面的第一個2,a[n]裡也有,則16和數列同時剔除2,然後第二個2,a[N]裡面已經剔除過2了,沒有2了,則把這個2,加入到a[N]中。
- 依次對每個剩下的數進行如此處理。
#include <stdio.h>#include <stdlib.h>#include <stdbool.h>#include <math.h>#define N 20bool isPrime(int n); //判斷一個數是不是質數 void splitNum(int arr[N], int num); // 拆分一個數為對應質數相乘的積 int main(int argc, char *argv[]){ int num = N; int arr[N]; //arr儲存1-num範圍內的所有質數 int arr1[N]; // arr1儲存1-num範圍內的所有數 int pnum = 0; int i = 0; for(i = 0; i < N; i++)// 初始化arr1數組 arr1[i] = i + 1; for(i = 2 ; i <= num; i++) //找出1- num 範圍內的所有質數 加入到整形數組中 { if(isPrime(i)) { arr[pnum] = i; pnum ++; } } unsigned long tmppro = 1; // 求出1-num範圍內所有質數的乘積,進行第一次初選 int j = 0; for(j = 0; j < pnum; j++) tmppro *= arr[j]; for(i = 0; i < N; i++) { if(tmppro % arr1[i] == 0) arr1[i] = 1; } for(i = 0; i < N; i++) // 處理 1-num範圍內除去質數,以及可以被整除的數,剩下的數 { if(arr1[i] != 1) { int copyArr[N]; // 拷貝質數數組資料 for(j = 0; j< pnum; j++) copyArr[j] = arr[j]; int tmp[N], k; splitNum(tmp, arr1[i]); //分拆這個數,因子儲存到tmp數組裡 for(j = 0; j < N; j++) { if(tmp[j] != 1) // 分析每個因子 { for(k = 0; k < pnum; k++) // 檢測temp[j]是否在copyArr[j]中 { if(copyArr[k] == tmp[j]) { copyArr[k] = 1; tmp[j] = 1; } } } } for(j = 0; j< N; j++) { if(tmp[j] != 1) { tmppro *= tmp[j]; arr[pnum] = tmp[j]; pnum ++; } } } } printf("%lu", tmppro); system("PAUSE"); return 0;}bool isPrime(int n){ int sqr = (int)sqrt(n + 1); int i; for(i = 2; i <= sqr; i++) { if(n % i == 0) return false; } return true; }void splitNum(int arr[N], int num){ int i; for(i = 0; i < N; i++) // 將數組的每個元素初始化為1 arr[i] = 1; int k = 2; // 從最小的質數2進行拆分 i = 0; while(k <= num) { if(num % k == 0) { arr[i] = k; i++; num = num / k; } else k++; }}