1.1 列舉類問題
· 列舉是什麼?
列舉也叫窮舉,是計算機解決問題最基本的策略。其方法是一一列舉所有的可能性,根據題意要求進行合理的判斷或計算,最終得到答案,本質上就是一種搜尋演算法
基礎的列舉就是人們常說的“暴力”求解。對於不同的問題,不可過分依賴“暴力”求解,應該根據具體的場景來進行具體分析,選擇更加簡潔和高效的演算法。
列舉就是用for
,while
等迴圈來實現的,通常都一個一個的去試。如果試的資料符合已知條件,則就認為,這個數就是要的答案,就不再列舉下去了。所謂列舉,其實就是慢慢去試過去。但列舉有個壞處,若資料很大,很多,則列舉的範圍就很廣,又費空間,還費時間。所以用列舉的時候要想好空間範圍,以確保達到時間的最簡,與空間的最省。
列舉演算法的運用場景就是適用於問題規模較小、解空間可窮舉的情況。
\(思路很好想,程式碼很好寫,只不過速度慢了一些。\)
· 總結一下:
- 運用迴圈把所有可能全試一遍,再根據題意做題。
- 列舉演算法優點在於簡單直觀,不需要複雜的數學推導,易於實現。
- 缺點那就是運算量過大,當問題的規模變大的時候,迴圈的階數越大,執行速度越慢,很容易超時。
1.2 列舉題目講解
· P1149 [NOIP2008 提高組] 火柴棒等式
· 大意:
給你 \(n\) 根火柴棍,你可以拼出多少個形如 \(A+B=C\) 的等式?等式中的 \(A\)、\(B\)、\(C\) 是用火柴棍拼出的整數(若該數非零,則最高位不能是 \(0\))。用火柴棍拼數字 \(0\sim9\) 的拼法如圖所示:
注意:
- 加號與等號各自需要兩根火柴棍;
- 如果 \(A\neq B\),則 \(A+B=C\) 與 \(B+A=C\) 視為不同的等式(\(A,B,C\geq0\));
- \(n\) 根火柴棍必須全部用上。
樣例 #1
樣例輸入 #1
14
樣例輸出 #1
2
· 講解
我們可以先得到\(0-9\)各需要多少根火柴棒,然後再推出二位數,三位數,四位數各需要多少火柴棒。處理完後,我們可以直接列舉\(A\)和\(B\)。(可以證明\(A和B\)最大值為1111
)、
\(Code:\)
點選我~ 獲取程式碼
#include<bits/stdc++.h>
using namespace std;
int ans=0,n; //答案和火柴棒個數
int z[3005]={6,2,5,5,4,5,6,3,7,6}; //0~9所需的火柴棒
void f() //預處理出10~1111的所需火柴棒
{
for(int i=10;i<=2222;i++)
z[i]=z[i/10]+z[i%10]; //i/10為十位,i%10為個位
}
int main()
{
f(); //預處理每個數字應該需要的火柴棒根數
cin>>n;
for(int i=0;i<=1111;i++)
for(int j=0;j<=1111;j++)
{
int k=i+j; //k是A+B的和
if(z[i]+z[j]+z[k]+4==n) //加數+加數+和+等號與加號所需的火柴棒個數 為n的話,ans就++.
++ans;
}
cout<<ans<<'\n'; //輸出
return 0;
}