今天看到了乙個題目,又想起了以前的乙個題目,這兩個題目也算是有相關性吧。在這裡總結一下。
題目1:不使用分支語句,迴圈語句,如:for while switch if goto 等關鍵字,輸出1-n的整數。
題目2:求1+2+....n,要求不能使用乘除法、for、while、if、else、switch、case等關鍵字。
這兩個題目的相關性就是不讓使用迴圈和分支語句,這就是難點所在。對於題目1,我想到的就是靜態成員變數,因為靜態成員變數在記憶體中只有乙份,所以可以共享,如果在這裡用遞迴的話,最大的難點就是遞迴的出口怎麼定義。目前,我沒有想到可行的遞迴的方法。要使用靜態成員變數,還有乙個可行的方法那就是在類中來使用,我們可以通過不同的物件來實現記憶體中共享的靜態成員變數的自增,從而輸出1-n的自然數。如下是**:
class d
private:
static int n;
};int d::n = 0;
void main()
對於題目1,還有乙個解法就是用巨集定義。因為巨集只是簡單的代入,所以我們可以利用這點性質來實現巢狀輸出1-n的自然數。例如:我們輸出1-1000,**如下:
#define a(x) x;x;x;x;x;x;x;x;x;x
void main()
對於題目2,有了題目1的解,我們應該會有乙個大概的思路。經上面的提示,我們應該會想到靜態變數的應用,而且也是在類中,我們需要兩個靜態變數,乙個用來儲存自增的自然數,乙個用來儲存隨時變化的和,這樣我們就可以達到目的。**如下:
class a
static int getsum()
private:
static int n;
static int sum;
};int a::n = 0;
int a::sum = 0;
void main()
題目2的另一種解法,真是讓我覺得演算法真的太精妙了。這也是看了july的文章後,才知道的這種解法。我根本就想不到這種方法。
重複一下這個思想吧。還是用遞迴,但是遞迴的難點就是出口怎麼控制。在這裡我們定義了兩個函式,乙個用來遞迴計算加和,另乙個函式用來控制遞迴的函式出口。那就有兩種情況,所以要二選一,那麼我們可以用bool變數來控制。怎麼根據給定的乙個整數n來判斷true和false呢?我們知道,如果n不是0,那麼n就代表true,!n就表示false,那麼!!n就表示true。當n是0時,正好相反。這就是關鍵所在,我們可以利用這點來控制遞迴函式出口。**如下:
class b
};b *arr[2];
class c : public b
};void main()
上面用到了虛函式,這就是強大之處。多型竟然在這裡用上了!我們用乙個陣列arr[2]儲存兩個變數,乙個是類b的物件的指標,另乙個是b類的子類的物件的指標。arr[1]->sum(n),就會呼叫c類中的sum函式,這裡就實現了遞迴,當n遞減到0時,由於!!0就是false,也就是0,那麼arr[0]->sum()就會呼叫b類中的sum函式,此函式實現了遞迴的結束,也就是遞迴的出口。從而,我們利用多型實現了1-n的自然數的和。
題外話,這種思想,那是得多麼精通c++的人才能想出來啊,自己太菜了!
計算數自然數序列中的1和2
問題 給定乙個自然數n,計算1,2,3.n中,出現1和2的數量。比如1,2,3.10,一共出現了3次,1,2,3.12,一共出現了7次。思路 比如計算54321,可以先計算50000,再計算50001 54321中1和2的個數,而後者又可以看成計算4321中1和2的個數,於是簡化了問題。其中計算50...
自然數從1到n之間,有多少個數字含有1
問題明確而簡單.for迴圈肯定是不好的.用遞推方法 定義h n 從1到9999.9999 n 個 9 之間含有1的數字的個數.定義f n 為n位數中含有1的數字的個數.由定義可知 h n f 1 f 2 f 3 f n 則f 1 h 1 1 f 2 10 1 8 h 1 f 3 10 2 8 h 2...
前n個自然數的平方和的求解方法 經典與獨創
用數數辦法求解 oo oooo。n個ooo ooo。n個o ooo。n個o n個o f n 1 2 3 n 2 3 n 3 n n n n 1 2 n 1 n 2 2 n 2 n 3 2 n n 1 n n 2 n n 1 2 n n 1 2 1 2 2 n n 1 2 2 3 2 n n 1 2 ...