列舉問題
【基本思路】確定列舉物件、列舉範圍和判定條件;一一列舉可能的解,驗證是否是問題的解。
【缺點】運算量比較大,解題效率不高,若列舉範圍太大(一般以不超過兩百萬次為限),在時間上就難以承受。
- 雄雞7元1只,母雞5元1只,小雞1元3只,花100元買100只雞,如果雄雞、母雞與小雞都必須有。則雄雞、母雞與小雞應該各買多少隻?
先考慮雄雞、母雞與小雞的取值範圍(當然也可從金額著手)
1)由於各種雞都必須有,所以雄雞的最高耗用金額為100-5-1=94元,取7的倍數,得91元,所以雄雞數範圍為1至13
2)母雞的最高耗用金額為100-7-1=92元,取5的倍數,得90元,所以母雞數範圍為1至18
3)小雞的最高耗用金額為100-7-5=88元,則小雞可買88*3=264只,但由於總雞數限制,小雞數不可>98,所以小雞數範圍為3至96
本題條件為:(1)小雞數+母雞數+雄雞數=100;(2)買小雞款+買母雞款+買雄雞款=100;(3)小雞數為3的倍數。
#include<stdio.h> int main(){ int c,h,x;//c……雄雞;h……母雞;x……小雞。 for(c=1;c<=13;c++) for(h=1;h<=18;h++){ if((100-c-h)%3==0&&(7*c+5*h+(100-c-h)/3)==100) printf("c:%d h:%d x:%d\n",c,h,100-c-h); } return 0; }
- 將1,2...9共9個數分成三組,分別組成三個三位數,且使這三個三位數構成1:2:3的比例,試求出所有滿足條件的三個三位數。例如:三個三位數192,384,576滿足以上條件。
此題資料規模不大,可進行列舉,但如果我們不假思索地以每一個數位為列舉物件,一位一位地去列舉:
for a:=1 to 9 do
for b:=1 to 9 do
………
for i:=1 to 9 do
其列舉次數達次,若分別設三個數為x,2x,3x,以x為列舉物件,窮舉範圍就減少為198次,在細節上再進一步優化,列舉範圍就可以更少
var t,x:integer; s,st:string; c:char; begin for x:=123 to 321 do{列舉所有可能的解} begin t:=0; str(x,st);{把整數x轉化為字串,存放在st中} str(x*2,s); st:=st+s; str(x*3,s); st:=st+s; for c:='1' to '9' do{列舉9個字元,判斷是否都在st中} if pos(c,st)<>0 then inc(t) else break;{如果不在st中,則退出迴圈} if t=9 then writeln(x,' ',x*2,' ',x*3); end; end.
- 一元三次方程求解,有的一元三次方程。給出該方程中各項的係數(a,b,c,d均為實數),並約定該方程存在三個不同實根(根的範圍在-100至100之間),且根與根之差的絕對值>=1。要求由小到大依次在同一行輸出這三個實根(根與根之間留有空格),並精確到小數點後2位。
記方程f(x)=0,若存在2個數x1和x2,且x1<x2,f(x1)*(x2)<0,則在(x1,x2)之間一定有一個根。
由題目的提示很符合二分法求解的原理,所以此題可以用二分法。用二分法解題相對於列舉法來說要複雜很多。此題是否能用列舉法求解呢?再分析一下題目,根的範圍在-100到100之間,結果只要保留兩位小數,我們不妨將根的值域擴大100倍(-10000<=x<=10000),再以根為列舉物件,列舉範圍是-10000到10000,用原方程式進行一一驗證,找出方程的解。
我們換一個角度來思考問題,設f(x)=ax^3+bx^2+cx+d,若x為方程的根,則根據提示可知,必有f(x-0.005)*f(x+0.005)<0,如果我們以此為列舉判定條件,問題就逆刃而解。另外,如果f(x-0.005)=0,那麼就說明x-0.005是方程的根,這時根據四捨五入,方程的根也為x。所以我們用(f(x-0.005)*f(x+0.005)<0) 和 (f(x-0.005)=0)作為判定條件。
var
k:integer; a,b,c,d,x:extended;
function f(x:extended):extended; {計算ax^3+bx^2+cx+d的值}
begin
f:=((a*x+b)*x+c)*x+d; end;
begin
read(a,b,c,d);
for k:=-10000 to 10000 do
begin
x:=k/100;
if (f(x-0.005)*f(x+0.005)<0) or (f(x-0.005)=0) then write(x:0:2,' ');
{若x兩端的函式值異號或x-0.005剛好是方程的根,則確定x為方程的根}
end;
end.