/*问题描述
  从一个大小为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();
    }
}