編程之美–2.20(程式理解和時間分析)

來源:互聯網
上載者:User
這是《編程之美》的2.20題目,給出一段C#代碼,要求不用電腦,理解程式並回答問題。下面是從C#代碼中改寫成的C++代碼:
#include <iostream>#include <limits>using namespace std;int main() {     int rg[] = {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,         20,21,22,23,24,25,26,27,28,29,30,31};     for(__int64 i =1; i < numeric_limits<__int64>::max(); i++) {         int hit = 0;         int hit1 = -1;         int hit2 = -1;         for(int j = 0; j < sizeof(rg)/sizeof(*rg) && (hit <= 2); j++) {              if((i % rg[j]) != 0) {                   hit++;                   if(hit == 1) {                       hit1 = j;                   } else if(hit == 2) {                       hit2 = j;                   } else break;              }         }         if(hit == 2 && hit1+1==hit2) {              cout << "find " << i << endl;              break;         }     }     return 0;}
參考連結:http://blog.csdn.net/jcwKyl/article/details/3889802
1. 首先看在滿足什麼條件,才會輸出i的值呢?先看條件hit == 2,該條件預示著:(i % rg[j]) != 0)要有且僅有兩次成立。再看條件 hit1+1==hit2,通過該條件可以得出滿足條件(i % rg[j]) != 0)的兩個數j1, j2必須是相鄰的。基於上面的分析,我們可以得出程式的輸出結果i應該滿足: i不能被2-31這30個數中的兩個相鄰的數整除,但能被其餘28個數整除。也就是說:i肯定是其它28個數的最小公倍數的整數倍。
如何找到滿足上麵條件的2個數呢?簡單的考慮,素數是滿足要求的,因為素數不可能被其他的自然數的乘機所整除。還有沒其他的數也滿足呢?
i不能被兩個相鄰的數整除,所以必然是i分解質因子後要麼i的質因子中不包括這兩個數的質因子,要麼是i的質因子的次數小於這兩個數中相同質因子的次數。舉個例子,假設8是滿足條件的兩個數之一(即8不能被其餘數的乘積所整除),很明顯我們可以找到一個反例--16,因為16i的一個因子,由於16能被8整除,那麼i必然能被8整除,假設不成立,所以8不是我們所求的數。但16是可以的,想想這是為什嗎?
那麼,只需要給2-31這30個數分解質因數,找一下是否有這樣的相鄰的兩個數,要麼它們的質因子中有其它數沒有的質因子,要麼對於相同的一個質因子,這兩個數包含這個質因子的次數高於其它所有次數(注意只需要該質因子高於其他所有rg中數的該因子的次數,而非其他所有該因子的次數之和,原因是最後只需最小公倍數)。為此建立一張表如下:



由上表中可以看出,只有16、17、19、23、25、27、29、31這幾個數包含次數最高的質因子。而相鄰的則只有16,17。所以,這段程式所要求的數i就是,它不能被16、17整除,但能被30個數中的其它28個數整除,最小的i就是其它28個數的最小公倍數,從上表中知道,這個最小的i是:8(2的3次方)*27(3的3次方)*25(5的2次方)*7*11*13*19*23*29*31,用計算機計算出這個數是:2123581660200。可以把上述程式中的for迴圈中的i初始化成這個數來檢驗。
參考連結:http://hi.baidu.com/silverxinger/item/4fd323b7c4803a98194697a5
拓展閱讀1:最小公倍數是如何求得的?素數是不能被1和自身數以外的其它數整除的數;素數X的N次方,是只能被X的N-1以下次方,1和自身數整除.
所以,在求A,B,C,D,E,…,Z的最小公倍數時,只需要把這些數分解為素數的N次方之間的乘積後,取各素因子的最高次方的乘積,就是這些數的最小公倍數.
舉例說明:
求756,4400,19845,9000的最小公倍數?
因756=2*2*3*3*3*7,4400=2*2*2*2*5*5*11,19845=3*3*3*3*5*7*7,9000=2*2*2*3*3*5*5*5,這裡有素數2,3,5,7,11.2最高為4次方16,3最高為4次方81,5最高為3次方125,7最高為2次方49,還有素數11.得最小公倍數為16*81*125*49*11=87318000.參考連結:http://baike.baidu.com/view/341375.htm
拓展閱讀2:JOJ的2042題目也是一個程式理解題目,這個題目非常有意思,給出了下面一段C++原始碼,要求計算出最後的輸出結果,原始碼如下:
#include<cstdio>int main(void){     int x = 987654321, c = 0, d = 1, e = 6;     while(x--){         c += d,         d += e,         e += 6;     }     printf("%d/n", c);     return 0;}


原題目如下:
We can use axioms to calculate programs just like what we do in algebras. Dijkstra is the one who advocates such constructive approach whereby a program is designed together with its correctness proof. In short, one has to start
from a given postcondition Q and then look for a program that establishes Q from the precondition. Often, analyzing Q provides interesting hints to finding the program. This approach is quite different from the well known Hoare Logic.
For example, the following program is calculated by Dijkstra's approach. Unfortunately, its annotation is lost so that its function is hard to grasp. You are to help with finding the final value of the variable c. Note that the
program is designed under 128-bit architecture.

代碼就是上面那一段。

這個題目通過小資料計算可以看出規律:x=1, c = 1; x=2, c=8; x=3, c=27; x=4, c=64,於是可以猜測這段程式是用來計算x^3的。用計算機計算出987654321^3,提交上去就AC了。

這個題目是超級大牛SIYEE出的。從題目本身的敘述中就學到了很多東西。又知道了一個數的立方還可以這樣計算。可惜數學功底差,不知道在數學上是如何推匯出來的。

參考連結:http://blog.csdn.net/jcwKyl/article/details/3889802

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.