1. 程式人生 > >藍橋杯--求3個數的最小公倍數

藍橋杯--求3個數的最小公倍數

          細心的人不難發現,這個坑爹的藍橋杯的OJ做的如此之粗糙與惡劣,還設定了坑爹的VIP,想錢之瘋魔程度,簡直是不忍直視啊。題目上面說1~N-1, 後面給的樣例就變成的從1~N裡面篩選,這種赤裸裸的扇自己臉的行為,我只能呵呵了。

       小規模吐槽完畢,接下來進入正題:

       這個題的意思就是要我們在1~N的範圍內找三個數,使他們的最小公倍數在這個範圍內的組合是最大的。那麼你的第一印象是什麼的?我的第一印象是找三個兩兩互質的數,這樣只需要相乘即可,就沒有需要約分的地方。

       接下來先說一個結論:大於1的兩個相鄰的自然數必定互質。

       而對於1~N的範圍,肯定是 n*(n-1)*(n-2)的乘積最大、如果這三個數還兩兩互質的話那就最棒了。

       如果n是奇數,那麼 n、n-1、n-2必定兩兩互質,要是有些糾結的話,那麼我們就分析在什麼情況下可能會存在公因子。n是奇數,那麼n,n-1,n-2一定是兩奇加一偶的情況。公因子2直接pass,因為只有一個偶數。假設剩下的n,n-2中有一個數能被3整除,那麼有公因子的數一定是n或n-2加減3才能得到的情況。為此,n,n-1,n-2的乘積不僅是最大的,而且一定兩兩互質。

       如果n是偶數,繼續分析n*(n-1)*(n-2),這樣的話n和n-2必定有公因子2,那麼就換成式子n*(n-1)*(n-3)。然後仔細思考一下,不行啊,若偶數本身就能被3整除的話,那麼式子n*(n-1)*(n-3)也不成立了,n和n-3就有公因子3,再仔細思考一下,式子就變成了(n-1)*(n-2)*(n-3),兩奇夾一偶的情況。

      程式碼如下:

  1. #include<iostream>
  2. #include<cmath>
  3. usingnamespace std;  
  4. int main()  
  5. {  
  6.     longlong n, number;  
  7.     cin>>n;  
  8.     if( n <= 2)  
  9.     {  
  10.         cout<<2;  
  11.     }  
  12.     elseif(n % 2)  
  13.     {  
  14.          number = n * (n - 1) * (n - 2);  
  15.          cout<<number;  
  16.     }  
  17.     else
  18.     {  
  19.         if( n % 3 == 0)  
  20.         {  
  21.             number = (n - 1) * (n - 2) * (n - 3) ;  
  22.         }  
  23.         else number = n * (n - 1) * (n - 3);  
  24.         cout<<number;   
  25.     }  
  26.     return 0;  
  27. }   


但是這個題的評測分數只給了我60分。

     這個曾經讓我以為我的推論是錯誤的,後來我把程式碼改為窮舉法。

  1. #include<iostream>
  2. usingnamespace std;  
  3. longlong gdb(longlong m, longlong n)  
  4. {  
  5.     longlong p;  
  6.     longlong r, temp;  
  7.     if(n < m)  
  8.     {  
  9.         temp = n;  
  10.         n = m;  
  11.         m = temp;  
  12.     }  
  13.     p = n * m;  
  14.     while(m != 0)  
  15.     {  
  16.         r = n % m;  
  17.         n = m;  
  18.         m = r;  
  19.     }  
  20.     return p / n;  
  21. }  
  22. int main()  
  23. {  
  24.     longlong n;  
  25.     longlong number;  
  26.     cin>>n;  
  27.     if(n <= 2)  
  28.     {  
  29.         cout<<n;  
  30.     }   
  31.     elseif(n % 2)  
  32.     {  
  33.         number = n * (n - 1) * (n - 2);  
  34.         cout<<number;  
  35.     }  
  36.     else
  37.     {  
  38.         longlong max = 0;  
  39.         for(longlong a = n; a >= n - 10; a--)  
  40.         {  
  41.             for(longlong b = n; b >= n - 10; b--)  
  42.             {  
  43.                 for(longlong c = n; c >= n - 10; c--)  
  44.                 {  
  45.                     number = gdb(a, gdb(b, c));  
  46.                     max = max > number? max: number;  
  47.                 }  
  48.             }  
  49.         }  
  50.         cout<<max;  
  51.     }  
  52.     return 0;   
  53. }   

        但是窮舉法的程式碼依舊是60分,讓我很是糾結。

        直到隔了一天,有一個跟我一樣糾結的人在c語言吧進行求助。c語言小吧 霧香_樓蘭 找到了原題網址。我才知道,這個收錢如流水,平臺做成渣的藍橋杯OJ,不僅抄題沒抄好,而且後臺資料都是他喵的錯的,論世上誰最坑爹,藍橋杯穩佔候選者一席。不服來辯。

       大家有自己的想法就去這個網址測評這道題吧。