1. 程式人生 > >ALGO-115_藍橋杯_算法訓練_和為T(枚舉)

ALGO-115_藍橋杯_算法訓練_和為T(枚舉)

正整數 scanf 技術 開始 logs n) 分享圖片 sum 不包含

問題描述
  從一個大小為n的整數集中選取一些元素,使得它們的和等於給定的值T。每個元素限選一次,不能一個都不選。
輸入格式
  第一行一個正整數n,表示整數集內元素的個數。
  第二行n個整數,用空格隔開。
  第三行一個整數T,表示要達到的和。
輸出格式
  輸出有若幹行,每行輸出一組解,即所選取的數字,按照輸入中的順序排列。
  若有多組解,優先輸出不包含第n個整數的;若都包含或都不包含,優先輸出不包含第n-1個整數的,依次類推。
  最後一行輸出總方案數。
樣例輸入
5
-7 -3 -2 5 9
0
樣例輸出
-3 -2 5
-7 -2 9
2
數據規模和約定
  1<=n<=22
  T<=maxlongint   集合中任意元素的和都不超過long的範圍

記:

一開始寫的代碼量大,很不便於理解

於是上網搜尋,參考了一篇使用二進制枚舉輸出的方法,代碼少且易讀,學習了

(代碼參考:https://blog.csdn.net/murphypu/article/details/69053861)

關於枚舉子集的方法(包含二進制枚舉):https://www.cnblogs.com/itlqs/p/5720784.html

解題思路:

題目要求:"若有多組解,優先輸出不包含第n個整數的;若都包含或都不包含,優先輸出不包含第n-1個整數的,依次類推。"

該輸出要求可以通過二進制枚舉輸出實現

二進制枚舉,以題目輸入為例

技術分享圖片

枚舉輸出(代表數組下標)與題意符合,故采用

AC代碼:

 1 #include <stdio.h>
 2 
 3 int main(void)
 4 {
 5     int i,j;
 6     int n;
 7     long long t,sum;
 8     long long arr[22+5];
 9     int count = 0;    
10     
11     scanf("%d",&n);
12     for (i = 0 ; i < n ; i ++)
13     {
14         scanf("
%lld",&arr[i]); 15 } 16 scanf("%lld",&t); 17 18 for (i = 1 ; i < (1<<n) ; i ++) 19 { 20 sum = 0; 21 for (j = 0 ; j < n ; j ++) 22 { 23 /*找數對應的二進制,其中二進制中為1的即是數組中要選擇的數*/ 24 if (i&(1<<j)) 25 { 26 sum += arr[j]; 27 } 28 } 29 30 if (sum == t) 31 { 32 for (j = 0 ; j < n ; j ++) 33 { 34 if (i&(1<<j)) 35 printf("%lld ",arr[j]); 36 } 37 printf("\n"); 38 count ++; 39 } 40 } 41 printf("%d",count); 42 return 0; 43 }

ALGO-115_藍橋杯_算法訓練_和為T(枚舉)