列舉:基於逐個嘗試答案的一種問題求解策略。
完美立方:
形如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 ...