/*问题描述 从一个大小为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的范围 【分析】一道深搜的题目,难点在于输出多组解的顺序。为了方便解决输出多组解的顺序的这个问题,需要从后想前搜索,然后把结果逆序输出就可以得到结果。 如例子,从9开始搜索,得到9 -2 -7,然后把它的顺序反一下输出就得到了一组解。而且这个解在另一组解5 -2 -3的前面先得到,所以最后把所有的解按逆序输出就得到了结果。*/ package test; import java.util.*; public class 和为T { static int count=0,n=0,t=0; static Stack<String> ans=new Stack<>();//存放答案 static int[] num; static boolean[] check; public static void main(String arg[]){ Scanner input=new Scanner(System.in); n=input.nextInt(); check=new boolean[n]; num=new int[n]; for(int i=0;i<n;i++){ num[i]=input.nextInt(); } t=input.nextInt(); dfs(n-1,0,new LinkedList<Integer>(),true); while(!ans.isEmpty()){ System.out.println(ans.pop()); } System.out.print(count); } static void dfs(int n,int tempT,LinkedList<Integer> tempNum,boolean judge){//tempT存放当前选择的数字的和,tempNum记录选择的数字,judge用来防止t=0时没有选择任何数字前的情况 for(int i=n;i>=0;i--){//从第n个数向前计算 if(!check[i]){//若该数字没有使用过 check[i]=true; tempNum.push(num[i]); dfs(i-1,tempT+num[i],tempNum,false); tempNum.pop(); check[i]=false; } } if(tempT==t&&!judge){//若和为T且不是未遍历过的数 count++; ans.push(toString(tempNum.iterator()));//将链表中的答案入栈 } } private static String toString(Iterator<Integer> iterator) {//将链表中的数字转换为字符串,并在每个数字中加上空格 // TODO Auto-generated method stub StringBuilder result=new StringBuilder(); while(iterator.hasNext()){ result.append(iterator.next()+" "); } return result.toString(); } }