枚舉算法是我們在日常中使用到的最多的一個算法,本篇將會介紹枚舉算法的思想與實例講解,在使用頻率上,枚舉算法在藍橋杯比賽里用的次數(shù)非常多,所以需要在平時多練習(xí)做題,畢竟實踐檢驗真理,畢竟枚舉在考試中出現(xiàn)的頻率非常高,可謂是得枚舉者得天下,下面我們就來講講枚舉。
一、 枚舉算法的思想
談到枚舉算法,所謂的枚舉算法就是按問題本身的性質(zhì),一一列舉出該問題所有可能的解,并在逐一列舉的過程中,檢驗每個可能解是否是問題的真正解,若是,我們采納這個解,否則拋棄它。在列舉的過程中,既不能遺漏也不應(yīng)重復(fù)。
(1)枚舉算法的定義:
在進行歸納推理時,如果逐個考察了某類事件的所有可能情況,因而得出一般結(jié)論,那么該結(jié)論是可靠 的,這種歸納方法叫做枚舉法。
(2)枚舉算法的思想是:
將問題的所有可能的答案一一列舉,然后根據(jù)條件判斷此答案是否合適,保留合適的,舍棄不合適的。
(3)使用枚舉算法解題的基本思路如下:
1. 確定枚舉對象、范圍和判定條件。
2. 逐一枚舉可能的解并驗證每個解是否是問題的解。
(4)枚舉算法步驟:
1. 確定解題的可能范圍,不能遺漏任何一個真正解,同時避免重復(fù)。
2. 判定是否是真正解的方法。
3. 為了提高解決問題的效率,使可能解的范圍將至最小。
(5)枚舉算法的流程圖如下所示:
先判斷值是否在范圍內(nèi),然后判斷是否符合條件,最后輸出或者取下一個值,直到結(jié)束,下面通過例題來學(xué)習(xí)一下這種算法思想。
二、枚舉算法的實例
以下是一個使用枚舉解題與優(yōu)化枚舉范圍的例子。
例題:
一個數(shù)組中的數(shù)互不相同,求其中和為0的數(shù)對的個數(shù)。
解題思路:
枚舉兩個數(shù)的代碼很容易就可以寫出來。
// C++ Version for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) if (a[i] + a[j] == 0) ++ans;
# Python Version for i in range(0, n): for j in range(0, n): if(a[i] + a[j] == 0): ans = ans + 1
來看看枚舉的范圍如何優(yōu)化。由于題中沒要求數(shù)對是有序的,答案就是有序的情況的兩倍(考慮如果 (a, b) 是答案,那么 (b, a) 也是答案)。對于這種情況,只需統(tǒng)計人為要求有順序之后的答案,最后再乘上2就好了。
不妨要求第一個數(shù)要出現(xiàn)在靠前的位置。代碼如下:
// C++ Version for (int i = 0; i < n; ++i) for (int j = 0; j < i; ++j) if (a[i] + a[j] == 0) ++ans;
# Python Version for i in range(0, n): for j in range(0, i): if(a[i] + a[j] == 0): ans = ans + 1
不難發(fā)現(xiàn)這里已經(jīng)減少了j 的枚舉范圍,減少了這段代碼的時間開銷。
我們可以在此之上進一步優(yōu)化。
兩個數(shù)是否都一定要枚舉出來呢?枚舉其中一個數(shù)之后,題目的條件已經(jīng)確定了其他的要素(另一個數(shù))的條件,如果能找到一種方法直接判斷題目要求的那個數(shù)是否存在,就可以省掉枚舉后一個數(shù)的時間了。較為進階地,在數(shù)據(jù)范圍允許的情況下,我們可以使用桶記錄遍歷過的數(shù)。
// C++ Version bool met[MAXN * 2]; memset(met, 0, sizeof(met)); for (int i = 0; i < n; ++i) { if (met[MAXN - a[i]]) ans += 1; met[MAXN + a[i]] = true; }
# Python Versionmet = [False] * MAXN * 2for i in range(0, n): if met[MAXN - a[i]]: ans = ans + 1 met[a[i] + MAXN] = True
C語言網(wǎng)提供由在職研發(fā)工程師或ACM藍橋杯競賽優(yōu)秀選手錄制的視頻教程,并配有習(xí)題和答疑,點擊了解:
一點編程也不會寫的:零基礎(chǔ)C語言學(xué)練課程
解決困擾你多年的C語言疑難雜癥特性的C語言進階課程
從零到寫出一個爬蟲的Python編程課程
只會語法寫不出代碼?手把手帶你寫100個編程真題的編程百練課程
信息學(xué)奧賽或C++選手的 必學(xué)C++課程
藍橋杯ACM、信息學(xué)奧賽的必學(xué)課程:算法競賽課入門課程
手把手講解近五年真題的藍橋杯輔導(dǎo)課程