枚舉非空真子集
阿新 • • 發佈:2018-07-06
main std 一次 cin 二進制 兩種 clas stream ret
第一種情況給定的集合是滿狀態的,也就是枚舉2的n次方種狀態下的每一種子集的情況。
for(int x=0;x<(1<<n);x++)
這裏的x是一個二進制數,其長度為n,取值為00000...00000~11111...11111的每一種狀態。
for(int i=0;i<n;i++) if(x&(1<<i))
這裏的i的取值為1,10,100,1000,10000...其目的就是一個一個去試x中對應位置的元素是1還是0,如果是1表示當前集合中有這個元素,否則沒有。
第二種情況給定的集合不一定是滿狀態的,這時要輸入一個全集s。
for(int x=s;x;x=s&(x-1))
這裏的x就是s的子集的一種情況了,後面的i還是類似簽名的道理,一位一位地去試有沒有當前這個元素。
完整實現如下,首先輸入全集元素個數n,進行一次枚舉,接下來輸入給定集合s進行子集的枚舉,這是兩種枚舉情況的舉例。
#include<iostream> using namespace std; int n,s; int main() { cin>>n; for(int x=0;x<(1<<n);x++) { for(int i=0;i<n;i++) if(x&(1<<i)) cout<<i+1<<" "; cout<<endl; } cin>>s; for(int x=s;x;x=s&(x-1)) { for(int i=0;i<n;i++) if(x&(1<<i)) cout<<i+1<<" "; cout<<endl; } return 0; }
枚舉非空真子集