OJ之路(第一天)

經過一夜難以入眠的煎熬,我戴着熊貓眼滾下牀,打開電腦,想着昨天那道做不出的題目,心裏有所不甘。於是,有了今天。

今天,我一打開電腦,進入oj系統,看着題目,信心滿滿。於是,有了以下的總結:

①這是一支開啓我訓練之門的鑰匙:

=================================================================================================================

題目描述如下:

有N個士兵站成一隊列, 現在需要選擇幾個士兵派去偵察。爲了選擇合適的士兵, 多次進行如下操作: 如果隊列超過三個士兵, 那麼去除掉所有站立位置爲奇數的士兵, 或者是去除掉所有站立位置爲偶數的士兵。直到不超過三個戰士,他們將被送去偵察。現要求統計按這樣的方法,總共可能有多少種不同的正好三個士兵去偵察的士兵組合方案。
注: 按上法得到少於三士兵的情況不統計。1 <= N <= 2的32次方-1
輸入格式
有多行,每行一個數字N,最後一行是0
輸出格式
對每一行的數字N,輸出針對N的方案數
直到沒有數字
輸入樣例
10
4
0
輸出樣例
2
0

=================================================================================================================

思考過程:

這裏是奇數分一半,偶數分一半,那麼我們可以這樣思考:

“等價轉換”思想:實際上這種做法等同於分左右兩半。

“遞歸“思想:你想一下,分成兩半後,又是同樣的問題(即繼續分兩半)--所謂的子問題,一直到不能或者不需要再分爲止。

=================================================================================================================

細節上引發的問題:

以上思考形成的算法會帶來一個問題:如果數據過大,那麼該程序的運行時間是難以接受的。

解決方法:

”記憶搜索“思想:當數據很大的時候,你會容易發現”數據小的部分“已經重複計算了很多次了,所以這種思想就是"把重複計算很多次的結果給儲存起來,等到以後

處理時遇到相同的問題,我們就可以直接拿結果來用,而不用再重複計算“。

其實”記憶搜索“這種思想在很多方面都有體現(特別是在遞歸上的應用):求高次冪運算(例如:2的100次方),fibnacci數列的非遞歸求法,給範圍求素數個數etc。

=================================================================================================================

源代碼:

#include <stdio.h>
//傳說中的記憶搜索,能夠解決一些超時問題(出現多次重複計算)
int record[10000];			
int DealWith(int m, int n)
{
	int tmp = n - m + 1;
	if (tmp < 10000 && record[tmp] != -1)
		return record[tmp];
	else if ( tmp < 3)
		return 0;
	else if ( tmp == 3)
		return 1;
	else {
		int ct = DealWith(m, m + tmp / 2 - 1) + DealWith(m + tmp / 2, n);
		if ( tmp < 10000 )
			record[tmp] = ct;
		return ct;
	}
}
int main()
{
	for (int i = 0; i < 10000; ++i)
		record[i] = -1;
	int n;
	while ( scanf( "%d", &n ) && n != 0 ) {
		printf("%d\n", DealWith( 1, n ) );
	}
	return 0;
}

=================================================================================================================

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章