列舉演算法 完美立方 生理週期 稱硬幣 熄燈問題

2021-10-05 04:37:35 字數 4756 閱讀 4685

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

完美立方:

形如a3= b3 + c3 + d3的等式被稱為完美立方等式。例如 123= 63 + 83 + 103 。編寫乙個程式,對任給的正整數n (n≤100),尋找所有的四元組(a, b, c, d),使得a3 = b3 + c3 + d3,其中a,b,c,d 大於 1, 小於等於n,且b<=c<=d。

解:cube = a, triple = (b,c,d)

四重迴圈列舉a,b,c,d ,a在最外層,d在最裡層,每一層都是從小到大列舉,a列舉範圍[2,n],b範圍 [2,a-1],c範圍 [b,a-1],d範圍 [c,a-1]。

#include

#include

/* cstdio是將stdio.h的內容用c++標頭檔案的形式表示出來。

stdio.h是c標準函式庫中的頭件,即:standard buffered input&output。

stdio.h是以往的c和c++的標頭檔案,cstdio是標準c++(stl),且cstdio中的函式都是定義在乙個命名空間std裡面的。

如果要呼叫這個名字空間的函式,必須得加std::或者在檔案中宣告using namespace std。提供基本的文字的輸入輸出流操作(包括螢幕和檔案等)。

由於c語言並沒有提供專用於文字輸入輸出的關鍵字,所以該庫是最普遍的c語言程式載入庫。

*/using

namespace std;

intmain()

生理週期:

人有體力、情商、智商的高峰日子,它們分別每隔23天、28天和33天出現一次。對於每個人,我們想知道何時三個高峰落在同一天。給定三個高峰出現的日子p,e和i(不一定是第一次高峰出現的日子), 再給定另乙個指定的日子d,你的任務是輸出日子d之後,下一次三個高峰落在同一天的日子(用距離d 的天數表示)。例如:給定日子為10,下次出現三個高峰同一天的日子是12,則輸出2。

解:

從d+1天開始,一直試到第21252 天,對其中每個日期k,看是否滿足

(k – p)%23 == 0 && (k – e)%28 == 0 &&(k-i)%33 == 0

#include

#include

using

namespace std;

#define n 21252

intmain()

return0;

}

稱硬幣:

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

解:假設這12枚硬幣分別為a、b、c、d、e、f、g、h、i、j、k、l。

abcd efgh even

abci efjk up

abij efgh even

k is the counterfeit coin and it is light.

第一行是測試資料組數。每組資料有三行,每行表示一次稱量的結果。天平左邊放置的硬幣、天平右邊放置的硬幣、平衡狀態。其中平衡狀態用"up","down』』, 或 "even』'表示, 分別為右端高、右端低和平衡。天平左右的硬幣數總是相等的。對於每一枚硬幣先假設它是輕的,看這樣是否符合稱量結果。如果符合,問題即解決。如果不符合,就假設它是重的,看是否符合稱量結果。把所有硬幣都試一遍,一定能找到特殊硬幣。

#include

#include

using

namespace std;

char left[3]

[7];

//天平左邊硬幣

char right[3]

[7];

//天平右邊硬幣

char result[3]

[7];

//結果

bool

isfake

(char c,

bool light)

;//light 為真表示假設假幣為輕,否則表示假設假幣為重

intmain()

elseif(

isfake

(c,false))

}}return0;

}bool

isfake

(char c,

bool light)

//light 為真表示假設假幣為輕,否則表示假設假幣為重

else

switch

(result[i][0

])}return

true

;}

熄燈問題:

有乙個由按鈕組成的矩陣, 其中每行有6個按鈕, 共5行 。每個按鈕的位置上有一盞燈。當按下乙個按鈕後, 該按鈕以及周圍位置(上邊, 下邊, 左 邊, 右邊)的燈都會改變狀態。

如果燈原來是點亮的, 就會被熄滅;如果燈原來是熄滅的, 則會被點亮。

• 在矩陣角上的按鈕改變3盞燈的狀態

• 在矩陣邊上的按鈕改變4盞燈的狀態

• 其他的按鈕改變5盞燈的狀態

與一盞燈毗鄰的多個按鈕被按下時,乙個操作會抵消另一次操作的結果。

給定矩陣中每盞燈的初始狀態,求一種按按鈕方案,使得所有的燈都熄滅。

第一行是乙個正整數n, 表示需要解決的案例數。每個案例由5行組成, 每一行包括6個數字。這些數字以空格隔開, 可以是0或1 ,0 表示燈的初始狀態是熄滅的 ,1 表示燈的初始狀態是點亮的。

輸出:對每個案例, 首先輸出一行, 輸出字串 「puzzle #m」, 其中m是該案例的序號。

接著按照該案例的輸入格式輸出5行,1 表示需要把對應的按鈕按下,0 表示不需要按對應的按鈕,每個數字以乙個空格隔開。

• 第2次按下同乙個按鈕時,

將抵消第1次按下時所產生的結果

每個按鈕最多隻需要按下一次

• 各個按鈕被按下的順序對最終的結果沒有影響

• 對第1行中每盞點亮的燈, 按下第2行對應的按鈕, 就可以熄滅第1行的全部燈

• 如此重複下去, 可以熄滅第1, 2, 3, 4行的全部燈

第一想法: 列舉所有可能的按鈕(開關)狀態, 對每個狀態計算一下最後燈的情況, 看是否都熄滅

– 每個按鈕有兩種狀態(按下或不按下) – 一共有30個開關, 那麼狀態數是230, 太多, 會超時

如何減少列舉的狀態數目呢?

基本思路: 如果存在某個區域性, 一旦這個區域性的狀態被確定, 那麼剩餘其他部分的狀態只能是確定的一種, 或者不多的n 種, 那麼就只需列舉這個區域性的狀態即可

本題是否存在這樣的 「區域性」 呢?

•經過觀察, 發現第1行就是這樣的乙個 「區域性」 – 因為第1行的各開關狀態確定的情況下, 這些開關作用過後, 將導致第1行某些燈是亮的, 某些燈是滅的

要熄滅第1行某個亮著的燈(假設位於第i列), 那麼唯一的辦法就是按下第2行第i列的開關(因為第1行的開關已經用過了, 而第3行及其後的開關不會影響

到第1行)

為了使第1行的燈全部熄滅, 第2行的合理開關狀態就是唯一的

第2行的開關起作用後,  為了熄滅第2行的燈, 第3行的合理開關狀態就也是唯一的

以此類推, 最後一行的開關狀態也是唯一的

只要第1行的狀態定下來, 記作a, 那麼剩餘行的情況就是確定唯一的了

推算出最後一行的開關狀態, 然後看看最後一行的開關起作用後, 最後一行的所有燈是否都熄滅:

• 如果是, 那麼a就是乙個解的狀態

• 如果不是, 那麼a不是解的狀態, 第1行換個狀態重新試試

只需列舉第1行的狀態, 狀態數是26 = 64

有沒有狀態數更少的做法?

列舉第一列, 狀態數是25 = 32

#include

#include

#include

#include

using

namespace std;

intgetbit

(char c,

int i)

void

setbit

(char

& c,

int i,

int v)

void

flip

(char

& c,

int i)

void

outputresult

(int t,

char result)

//輸出結果

cout << endl;}}

intmain()

}for

(int n =

0; n <64;

++n )}if

( i <4)

lights[i+1]

^= switchs;

//改下一行的燈

switchs = lights[i]

;//第i+1行開關方案和第i行燈情況同}if

( lights[4]

==0)}

// for( int n = 0; n < 64; n ++ )

}return0;

}

演算法基礎 完美立方 列舉

題目 完美立方 形如a3 b3 c3 d3的等式被稱為完美立方等式。例如 123 63 83 103 編寫乙個程式,對任給的正整數n n 100 尋找所有的四元組 a,b,c,d 使得a3 b3 c3 d3,其中a,b,c,d 大於 1,小於等於n,且b c d。輸入 乙個正整數n n 100 輸出...

生理週期 列舉 演算法學習

問題 人生來就有三個生理週期,分別為體力 感情和智力週期,它們的週期長度為23天 28天和33天。每乙個週期中有一天是高峰。在高峰這天,人會在相應的方面表現出色。例如,智力週期的高峰,人會思維敏捷,精力容易高度集中。因為三個週期的周長不同,所以通常三個週期的高峰不會落在同一天。對於每個人,我們想知道...

列舉 完美立方Python演算法實現

題目 形如a 3 b 3 c 3 d 3 的等式被稱為完美立方等式。例如 12 3 6 3 8 3 10 3 編寫乙個程式,對任給的正整數n n 100 尋找所有的四元組 a,b,c,d 使得a 3 b 3 c 3 d 3 其中a,b,c,d 大於 1,小於等於n,且b c d。輸入 乙個正整數n ...