本篇介紹子集生成演算法:給定乙個集合,列舉所有可能的子集。為了簡單起見,本節討論的集合彙總沒有重複元素。
輸入:整數n。
輸出:對於集合,列舉所有可能的子集。
執行結果:
增量構造法。
第一種思路是一次選出乙個元素放到集合中。
void print_subset_add(int n,int *a,int cnt)
按照和輸出兩次了。
在列舉子集的增量法巨集中,需要使用定序的技巧,避免同乙個集合列舉兩次。
位向量法。
第二種思路是構造乙個位向量b[i],而不是直接構造子集a本身,其中b[i]=1,當且僅當i在子集a中,遞迴實現如下:
void print_subset_b(int n,int *b,int cnt)
的子集s:從右往左第i位(各位從0開始編號)表示元素i是否在集合s中。
為了處理方便,最右邊的位總是對應元素9,而不是元素1.
可以用二進位制表示子集,其中從右往左第i位(從0開始編號)表示元素i是否在集合中(1表示「在」,0表示「不在」)
此時僅表示出集合是不夠的,還需要對集合進行操作。幸運的是,常見的集合運算都可以用位運算子簡單實現。
當用二進位制表示子集時,位運算中的按位與,或,異或對應集合的交、並和對稱差。
這樣,不難用下面的程式輸出子集s對應的各個元素:
void print_subset_binary(int n,int s)
{ //二進位制法
for(int i=0;i而列舉子集和列舉整數一樣簡單:
for(int i=0;i
列舉暴力求解
題目描述 有n個賭徒打算賭一局。規則是 每人下乙個賭注,賭注為非負整數,且任意兩個賭注都不相同。勝者為賭注恰好是其餘任意三個人的賭注之和的那個人。如果有多個勝者,我們取賭注最大的那個為最終勝者。例如,a,b,c,d,e分別下賭注為2 3 5 7 12,最終勝者是e,因為12 2 3 7。輸入輸入包含...
暴力求解總結
輸入正整數n,按從小到大的順序輸出所有形如abcde fghij n的表示式,其中a j恰好為數字0 的乙個排列 可以有前導0 2 n 79。樣例輸入 62 樣例輸出 79546 01283 62 94736 01528 62 分析 分成兩部分加一些細節處理。列舉數字 分母 至少是四位數,從1000...
暴力求解法
1 簡單列舉 輸入正整數n,按從小到大的順序輸出所有形如abcde fghij n的表示式,其中a j恰好位數字0 9的乙個排序 可以有前導0 2 n 79.樣例輸入 樣例輸出 79546 01283 62 94736 01528 62 思路 只要列舉fghij就可以算出abcde,然後判斷所有數字...