切換
舊版
前往
大廳
主題

ZeroJudge - a456: 子集合 解題心得

Not In My Back Yard | 2019-05-14 23:28:37 | 巴幣 0 | 人氣 437

題目連結:


題目大意:
給定一正整數 T ,代表有 T 組測試資料。每組測試資料佔一列,每列有一正整數 N (1 ≦ N ≦ 15),代表有一集合包含正整數 1 ~ N 。

求此集合的所有子集合。每個子集合佔一列,當子集合為空集合時輸出「{0}」。子集合的輸出順序以元素個數由小到大排,元素個數一樣時照字典序排。輸出格式參見範例輸出。



範例輸入:
2
1
2


範例輸出:
{0}
{1}

{0}
{1}
{2}
{1,2}


解題思維:
練習深度優先搜尋(DFS)的題目。

因為集合內的數字為 1 ~ N ,且自集合的輸出順序是先照個數,再照字典序。因此,我們的函式為:
DFS(now, toPick)
now 代表現在要挑或是不挑哪個數字;toPick 則代表現在要挑幾個數字。

先判斷如果 toPick > 0 ,則我們先挑現在的數字並遞迴呼叫
DFS(now + 1, toPick - 1)
接著,如果 N - now > toPick ,則試著不挑現在的數字並遞迴呼叫
DFS(now + 1, toPick)
若皆非以上情況,則回到上一層的遞迴堆疊。

而遞迴的停止條件為 now = N + 1 的時候,輸出此時挑的數字,並直接回到上一層。


而我們在 main 函式的時候,依序呼叫 DFS(1, 1) 、DFS(1, 2) 、……、DFS(1, N) 。這樣便可以先照子集合的個數排好字集合的順序,而上面的遞迴順序則決定了字典序的排列。

此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

更多創作