Problem:
Score : 300 points

Problem Statement

Tak has N cards. On the i-th (1 \leq i \leq N) card is written an integer x_i.
He is selecting one or more cards from these N cards, so that the average of the integers written on the selected cards is exactly A.
In how many ways can he make his selection?

Constraints

1 \leq N \leq 50

1 \leq A \leq 50

1 \leq x_i \leq 50

N,\,A,\,x_i are integers.

Partial Score

200 points will be awarded for passing the test set satisfying 1 \leq N \leq 16.

Input

The input is given from Standard Input in the following format:

N A
x_1 x_2 ... x_N

Output

Print the number of ways to select cards such that the average of the written integers is exactly A.

Sample Input 1

4 8
7 9 8 9

Sample Output 1

5

The following are the 5 ways to select cards such that the average is 8:

Select the 3-rd card.

Select the 1-st and 2-nd cards.

Select the 1-st and 4-th cards.

Select the 1-st, 2-nd and 3-rd cards.

Select the 1-st, 3-rd and 4-th cards.

Sample Input 2

3 8
6 6 9

Sample Output 2

0

Sample Input 3

8 5
3 6 2 8 7 6 5 9

Sample Output 3

19

Sample Input 4

33 3
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3

Sample Output 4

8589934591

The answer may not fit into a 32-bit integer.

Solution in Java7 (OpenJDK 1.7.0) (judge verdict: Time Limit Exceeded)

import java.util.Arrays;
import java.util.Scanner;

/**
 * http://arc060.contest.atcoder.jp/tasks/arc060_a
 * @author Cummin
 */

public class Main {
   
    static int N ;
    static int A ;
    static int plus[], minus[], zero[] ;
    static int plus_i, minus_i, zero_i ;
    
    public static void main(String[] args) {
//        System.out.printf("At Coder Regular Contest 060 問題C \n") ;
        Scanner sc = new Scanner(System.in);
        N = sc.nextInt() ;
        A = sc.nextInt() ;
        plus = new int[N];
        minus = new int[N] ;
        zero = new int[N] ;
        for (int i=0 ; i<N; i++) {
            plus[i] = 51; minus[i] = 51 ;
        }
        for (int i= 0 ; i<N; i++) {
            int x ;
            x = sc.nextInt() ;
            if (x<A) {
                minus[minus_i] = A - x ;
                minus_i ++ ;
            }else if (x>A) {
                plus[plus_i] = x - A ;
                plus_i ++ ;
            }else { // x==A
                zero[zero_i] = 0 ;
                zero_i ++ ;
            }
        }
        
        if (plus_i > minus_i) {
            int x ;
            x = plus_i ; plus_i = minus_i; minus_i = x ;
            int xx[] ;
            xx = plus ; plus = minus ; minus = xx ;
        }
        
        System.out.println(solve()) ;    
    }
    
    static long solve() {
        long cnt = 0 ;
        int plus_sum[] ;
        plus_sum = comb_list(plus_i, plus) ;

        for (long j = 1; j < power_2(minus_i); j++) {
            int minus_sum;
            minus_sum = comb_add(j, minus);
            for (int i = 1; i < power_2(plus_i); i++) {
                //System.out.printf("plus_sum[%d]=%d, minus_sum[j=%d]=%d \n", i, plus_sum[i],j, minus_sum);
                if (minus_sum < plus_sum[i]) continue ;
                if (plus_sum[i] == minus_sum) {
                    cnt++ ;
                    continue ;
                }
                if (plus_sum[i] > minus_sum) break ;
            }
        }
     
        if (zero_i >0 ) {
            //System.out.printf("cnt=%d, zero_i=%d, p2=%d \n", cnt, zero_i, power_2(zero_i)) ;
            cnt = (cnt * power_2(zero_i)) + power_2(zero_i)-1 ; // plus/minusとゼロの組み合わせ + zeroだけで構成する場合
            return cnt ;
        } else 
            return cnt;
    }

    static int[] comb_list(int n, int[] X) {
        // n<= 25 程度である必要がある
        int sum[] = new int[(int) power_2(n)];
        for (int i = 0; i < power_2(n); i++) {
            sum[i] = comb_add(i, X) ;
        }
        Arrays.sort(sum);
        return sum;
    }

    static int comb_add(long n, int[] X) {
        int count = 0;
        int sum = 0 ;
        while (n > 0) {
            if ((n & 0x01) == 1) {
                sum = sum + X[count];
            }
            count++;
            n = n >> 1;
        }
        return sum;
    }

    static long power_2(int n) { // n個の要素の組み合わせは、2^n通り
        long a = 1 ;
        for (int i=1 ; i<=n ; i++) {
            a = a+a ;
        }
        return a ;
    }
    
}