「列舉」真的要嘗試所有情況嗎?

2021-10-02 06:43:01 字數 2418 閱讀 2069

基於逐個嘗試答案的一種問題求解策略

列舉雖然是一種逐個嘗試的問題求解策略,但是也是可以進行優化的,有些可能的答案或者可能的猜測在進行稍加判斷後,就可以直接排除掉,從而避免代入問題進行求解,進一步節省時間。具體的優化方法,往往要根據具體問題具體分析,沒有統一的標準。

**問題描述:**形如a3=

b3+c

3+d3

a^3=b^3+c^3+d^3

a3=b3+

c3+d

3的等式被稱為完美立方等式。例如:123

=63+

83+1

0312^3=6^3+8^3+10^3

123=63

+83+

103。編寫乙個程式,對任意給定的整數n(n

≤100

)n(n\le100)

n(n≤10

0),尋找所有的四元組(a,

b,c,

d)(a,b,c,d)

(a,b,c

,d),使得a3=

b3+c

3+d3

a^3=b^3+c^3+d^3

a3=b3+

c3+d

3,其中a,b

,c,d

a,b,c,d

a,b,c,

d大於1,小於等於n

nn,且b≤c

≤db\le c\le d

b≤c≤

d**問題描述:**人有體力、情商、智商的高峰日子,它們分別每隔23天、28天和33天出現一次。對於每個人,我們想知道何時這三個高峰落在同一天。給定三個高峰出現的日子p,e

,ip,e,i

p,e,

i(不一定是第一次高峰出現的日子),再給定另乙個指定的日子d

dd,你的任務是輸出日子d

dd之後,下一次三個高峰落在同一天的日子(用距離d

dd**問題描述:**有 12

1212

枚硬幣。其中有 11

1111

枚真幣和 1

11 枚假幣。假幣和真幣的重量不同,但不知道假幣比真幣輕還是重。現在,用一架天平稱了這些幣三次,告訴你稱量結果,請你找出假幣並且確定假幣是輕是重(資料保證一定能找出來)。

**問題描述:**有乙個由按鈕組成的矩陣,其中每行有6個按鈕,共5行。每個按鈕的位置上有一盞燈。當按下乙個按鈕後,該按鈕以及周圍位置(上邊、下邊、左邊、右邊)的燈都會改變一次。即,如果燈原來是點亮的,就會被熄滅;如果燈原來是熄滅的,則會被點亮。在矩陣角上的按鈕改變3盞燈的狀態;在矩陣邊上的按鈕改變4盞燈的狀態;其他的按鈕改變5盞燈的狀態。

在上圖中,左邊矩陣中用x標記的按鈕表示被按下,右邊的矩陣表示燈狀態的改變。對矩陣中的每盞燈設定乙個初始狀態。請你按按鈕,直至每一盞等都熄滅。與一盞燈毗鄰的多個按鈕被按下時,乙個操作會抵消另一次操作的結果。在下圖中,第2行第3、5列的按鈕都被按下,因此第2行、第4列的燈的狀態就不改變。

請你寫乙個程式,確定需要按下哪些按鈕,恰好使得所有的燈都熄滅

解題(優化)思路

示例**

#include #include #include using namespace std;

char orilights[5]; // 燈的原始狀態

char lights[5]; // 變化之後燈的狀態

char result[5]; // 結果

// 乙個字元(char) 有 8 位(bit)

// 取字元 c 的第 i 個位元

int getbit(char c, int i)

// 設定字元 c 的第 i 個位元為 v

void setbit(char & c, int i, int v)

else

}// 將字元 c 的第 i 位翻轉

void flipbit(char & c, int i)

void outputresult(int t, char result)

cout<

flipbit(lights[i], j);

if(j < 5) }}

// 翻轉下一行燈的狀態

if (i < 4)

switchs = lights[i];

}if(lights[4] == 0)

} }return 0;

}

**細節分析

雖然列舉是一種基於逐個嘗試答案的一種問題求解策略,但是這並不意味著我們無法對其進行優化,有一些問題在進行稍加判斷後就可以縮小嘗試的範圍,進而避免了一些不可能情況的嘗試,可以極大的提高演算法效率。

回文數的判斷(考慮所有情況)

如下所有情況 1.當數值為負數時,返回false 即負數不是回文數 2.當數值最後乙個數為0並且這個數值本身不是0時,返回false 3.如果是使用數值反轉比較的話,需要考慮溢位的情況在此,我使用的是數值反轉的思想,不過鑑於資料溢位的情況,在這裡並不是反轉整個數值,而是將數值進行折半反轉賦值給乙個數...

列舉組合的所有情況(多層巢狀for迴圈與遞迴)

從n個元素中一次抽取m個元素,則共有c n,m 種可能的情況。那麼怎樣將組合的所有可能情況一一枚舉出來呢?以1至10共10個數字為例 int array new int 10 for int i 0 ic 10,1 即從10個數字中抽取1個數字 我們可以用for迴圈將其一一枚舉出來 for int ...

DFS求解出棧順序,輸出所有情況

給定乙個入棧順序,輸出所有出棧順序及其方法數。對於乙個一入棧的的數,他有兩種選擇,出棧進而輸出,或者不出棧,等待新的元素進棧,不論哪一種操作,操作完成之後都會形成乙個新的序列,這跟進行出棧,入棧操作之前一樣,因此可以用遞迴的方法來模擬實現。輸入的引數有3個,輸入佇列,中間用來儲存的棧,用於輸出的佇列...