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 C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Linq;
using System.Collections;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using static System.Console;
using static System.Math;
using static NotFounds.MyMath;
using static NotFounds.MyUtility;

namespace NotFounds
{
    public class Program
    {
        public static void Main(string[] args)
        {
            new Program().Solve();
        }

        int N;
        int A;
        int[] x;
        private void Solve()
        {
            var cin  = new MyInputStream();
            N = cin.ReadInt();
            A = cin.ReadInt();
            x = new int[N];
            for (var i = 0; i < N; ++i)
                x[i] = cin.ReadInt();
            if (N <= 16) WriteLine(dfs(0, 0, 0) - 1);
            else WriteLine();
        }

        private long dfs(int i, int v, int c)
        {
            if (i == N) return ((v == A * c) ? 1 : 0);
            return dfs(i + 1, v, c) + dfs(i + 1, v + x[i], c + 1);
        }
    }

    public class MyInputStream
    {
        private char separator = ' ';
        private Queue<string> inputStream;
        public MyInputStream(char separator = ' ')
        {
            this.separator = separator;
            inputStream = new Queue<string>();
        }

        public string Read()
        {
            if (inputStream.Count != 0) return inputStream.Dequeue();
            string[] tmp = Console.ReadLine().Split(separator);
            for (int i = 0; i < tmp.Length; i++)
            {
                inputStream.Enqueue(tmp[i]);
            }
            return inputStream.Dequeue();
        }
        public string ReadLine()   => Console.ReadLine();
        public int    ReadInt()    => int.Parse(Read());
        public long   ReadLong()   => long.Parse(Read());
        public double ReadDouble() => double.Parse(Read());
    }

    public class MyMath
    {
        // nx = x + dxy[i], ny = y + dxy[i + 1] (i = 0..3)
        public static int[] dxy = new int[] {0, 1, 0, -1, 0};

        /// <summary>最大値</summary>
        public static int INF = int.MaxValue >> 1;

        /// <summary>許容する誤差ε</summary>
        public static double EPS = 1e-11;

        /// <summary>よく使う素数</summary>
        public static long MOD = 1000000007;

        /// <summary>2つのスカラー値が等しいかどうか</summary>
        public static bool EQ(double d1, double d2) => (Math.Abs(d1 - d2) < EPS);

        /// <summary>x^n % m</summary>
        public static long PowMod(long x, long n, long m)
        {
            long ans = 1;
            long mul = x;
            for (; n > 0; n >>= 1, mul = (mul * mul) % m)
            {
                if ((n & 1) == 1) ans = (ans * mul) % m;
            }
            return ans % m;
        }

        /// <summary>n! % m</summary>
        public static long FactMod(int n, long m)
        {
            long ans = 1;
            for (int i = 2; i <= n; i++)
            {
                ans *= i;
                ans %= m;
            }
            return ans;
        }

        /// <summary>n!</summary>
        public static long Fact(int n)
        {
            long ans = 1;
            for (int i = 2; i <= n; i++) ans *= i;
            return ans;
        }

        /// <summary>nCr % mod</summary>
        public static long ConbMod(int n, int r, long m)
        {
            long mul = FactMod(n, m);
            long div = (FactMod(r, m) * FactMod(n - r, m)) % m;
            long inv = PowMod(div, m - 2, m);
            return (mul * inv) % m;
        }

        /// <summary>nCr</summary>
        public static long Conb(int n, int r)
        {
            long mul = Parm(n, r);
            long div = Fact(r);
            return mul / div;
        }

        /// <summary>nPr</summary>
        public static long Parm(int n, int r)
        {
            long ans = 1;
            for (int i = n; i >= r; i--) ans *= i;
            return ans;
        }

        /// <summary>最大公約数</summary>
        public static long Gcd(long m, long n)
        {
            if (n == 0) return m;
            if (m < n) MyUtility.Swap(ref m, ref n);
            long tmp;
            while ((tmp = m % n) != 0)
            {
                m = n;
                n = tmp;
            }
            return n;
        }

        /// <summary>最小公倍数</summary>
        public static long Lcm(long m, long n)
        {
            return m * n / Gcd(m, n);
        }

        /// <summary>ピタゴラス</summary>
        public static double Dist(double x, double y)
        {
            return Math.Sqrt(x * x + y * y);
        }

        /// <summary>素数判定</summary>
        public static bool isPrime(int n)
        {
            if (n < 2) return false;
            if ((n & 1) == 0) return n == 2 ? true : false;
            for (int i = 3; i * i <= n; i += 2)
            {
                if (n % i == 0) return false;
            }
            return true;
        }

        /// <summary>素数取得(random)</summary>
        public static IEnumerable<int> GetPrimes(int n)
        {
            return Enumerable.Range(2, n - 1).AsParallel().Where(x => isPrime(x));
        }

        /// <summary>ビットの数を数える</summary>
        public static int BitCount(uint n)
        {
            n = (n & 0x55555555) + ((n >> 1) & 0x55555555);
            n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
            n = (n & 0x0f0f0f0f) + ((n >> 4) & 0x0f0f0f0f);
            n = (n & 0x00ff00ff) + ((n >> 8) & 0x00ff00ff);
            return (int)((n & 0x0000ffff) + ((n >> 16) & 0x0000ffff));
        }

        public static string FizzBuzz(long n)
        {
            var ret = "";
            if (n % 3 == 0) ret += "Fizz";
            if (n % 5 == 0) ret += "Buzz";
            return ret == "" ? n.ToString() : ret;
        }
    }

    public class MyUtility
    {
        /// <summary>二分法:単調増加(n次関数を微分して渡しても可)</summary>
        public static double binarySearch(Func<double, double> calc, double min, double max, double target)
        {
            var mid = 0.0;
            for (int i = 0; i < 50; i++)
            {
                mid = min + (max - min) / 2.0;
                if (calc(mid) < target) min = mid;
                else max = mid;
            }
            return mid;
        }
        public static double binarySearch(Func<double, double> calc, double min, double max)
        {
            return binarySearch(calc, min, max, 0.0);
        }

        /// <summary>三分法:凸を探索<summary>
        public static double ternarySearch(Func<double, double> calc, double min, double max)
        {
            var left  = 0.0;
            var right = 0.0;
            for (int i = 0; i < 200; i++)
            {
                left  = (min * 2 + max) / 3.0;
                right = (min + max * 2) / 3.0;
                if (calc(left) < calc(right)) max = right;
                else min = left;
            }
            return (left + right) * 0.5;
        }

        /// <summary>ニュートン法</summary>
        /// calc : 元の方程式( = 0), calcdash : calcの微分形
        public static double newtonSearch(Func<double, double> calc, Func<double, double> calcdash)
        {
            var ans0 = 0.0;
            var ans1 = calc(ans0) / calcdash(ans0);
            for (int i = 0; i < 100; i++)
            {
                if (MyMath.EQ(ans0 - ans1, 0.0)) break;
                ans1 = ans0;
                ans0 -= calc(ans0) / calcdash(ans0);
            }
            return ans0;
        }

        public static int Coin(int[] coins, int price)
        {
            var N = coins.Length;
            var dp = new int[price + 1]; dp[0] = 0;
            for (var i = 1; i <= price; i++) dp[i] = int.MaxValue;
            for (var i = 1; i <= price; i++)
                for (var j = 0; j < N; j++)
                    if (i >= coins[j]) dp[i] = Math.Min(dp[i], dp[i - coins[j]] + 1);
                    else dp[i] = Math.Min(dp[i], dp[i - 1] + 1);
            return dp[price];
        }

        /// <summary>2値を入れ替える</summary>
        public static void Swap<T>(ref T m, ref T n)
        {
            T tmp = m;
            m = n;
            n = tmp;
        }

        /// <summary>値を出力する</summary>
        public static void Dump(params object[] data)
        {
            data.Dump();
        }
    }

#region extentions
    public static class MyExtentions
    {
        public static int CountStringOfString(this string source, string target)
        {
            int cnt = 0;
            int targetLen = target.Length;
            if (targetLen == 0) return 0;
            for (int i = 0; i <= source.Length - targetLen; i++)
            {
                int tmp = source.IndexOf(target, i);
                if (tmp != -1)
                {
                    cnt++;
                    i = Math.Max(tmp + targetLen - 1, 0);
                }
                else break;
            }
            return cnt;
        }

        public static int Max(this int source, int num)
        {
            return Math.Max(source, num);
        }

        public static int Min(this int source, int num)
        {
            return Math.Min(source, num);
        }
    }

    public static class MyEnumerableExtentions
    {
        public static string ConcatWith<T>(this IEnumerable<T> source, string separator,
                string format, IFormatProvider provider = null) where T : IFormattable
        {
            return source.Select(x => x.ToString(format, provider)).Aggregate((a, b) => a + separator + b);
        }

        public static string ConcatWith<T>(this IEnumerable<T> source, string separator)
        {
            return string.Join(separator, source);
        }

        public static void ForEach<T>(this IEnumerable<T> source, Action<T, int> func)
        {
            foreach (var item in source.Select((x, i) => new { val = x, idx = i }))
                func(item.val, item.idx);
        }

        public static void ForEach<T>(this IEnumerable<T> source, Action<T> func)
        {
            foreach (var item in source)
                func(item);
        }

        public static void Dump<T>(this IEnumerable<T> source)
        {
            Console.WriteLine("{ " + source.ConcatWith(", ") + " }");
        }

        public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)
        {
            return source.OrderBy(x => Guid.NewGuid());
        }

        public static bool IsEmpty<T>(this IEnumerable<T> source)
        {
            return !source.Any();
        }

        public static string MaxLengthString(this IEnumerable<string> source)
        {
            return source.Aggregate("", (max, s) => s.Length > max.Length ? s : max);
        }

        public static string MinLengthString(this IEnumerable<string> source)
        {
            return source.Aggregate("", (min, s) => (s.Length < min.Length || min == "") ? s : min);
        }

        public static IEnumerable<IEnumerable<T>> Permutations<T>(this IEnumerable<T> source)
        {
            if (source.Count() != 0)
            {
                int index = 0;
                foreach (var item in source)
                {
                    var allOtherItems = source.RemoveAt(index++);
                    foreach (var permutation in allOtherItems.Permutations())
                    {
                        yield return new[] {item}.Concat(permutation);
                    }
                }
            }
            else {yield return new T[0];}
        }

        public static IEnumerable<T> RemoveAt<T>(this IEnumerable<T> source, int indexToRemove)
        {
            int index = 0;
            foreach (T item in source)
                if (index++ != indexToRemove)
                    yield return item;
        }
    }
#endregion

    public class Graph
    {
        private struct Edge
        {
            public int  To;
            public long Cost;
            public Edge(int t, long c)
            {
                this.To   = t;
                this.Cost = c;
            }
        }

        private struct Node : IComparable<Node>
        {
            public int  Pos;
            public long Cost;
            public Node(int p, long c)
            {
                this.Pos  = p;
                this.Cost = c;
            }
            public int CompareTo(Node obj)
            {
                return (int)(this.Cost - obj.Cost);
            }
        }

        private List<List<Edge>> g;
        private int N { get; set; }
        public Graph(int size)
        {
            N = size;
            g = new List<List<Edge>>(size);
            for (int i = 0; i < size; i++) g.Add(new List<Edge>());
        }

        public List<long> Dijkstra(int start = 0)
        {
            long Inf = (long)MyMath.INF << 16;
            var q = new PriorityQueue<Node>();
            q.Enqueue(new Node(start, 0));
            var ret = new List<long>(N);
            for (int i = 0; i < N; i++) ret.Add(Inf);

            while (q.Any())
            {
                var tmp = q.Dequeue();
                if (ret[tmp.Pos] == Inf) ret[tmp.Pos] = tmp.Cost;
                else continue;

                foreach (var e in g[tmp.Pos])
                    q.Enqueue(new Node(e.To, e.Cost + tmp.Cost));
            }

            return ret;
        }

        // 戻り値がnullのとき、負の閉路を含む
        public List<long> BellmanFord(int start = 0)
        {
            long Inf = (long)MyMath.INF << 16;
            var ret = new List<long>(N);
            for (int i = 0; i < N; i++) ret.Add(Inf);
            ret[start] = 0;
            for (int i = 0; i < N; i++)
            {
                for (int j = 0; j < N; j++)
                {
                    for (int k = 0; k < g[j].Count(); k++)
                    {
                        var e = g[j][k];
                        if (ret[j] != Inf && ret[e.To] > ret[j] + e.Cost)
                        {
                            ret[e.To] = ret[j] + e.Cost;
                            if (i == N - 1) return null;
                        }
                    }
                }
            }

            return ret;
        }

        public void AddDirectedEdge(int from, int to, long cost)
        {
            g[from].Add(new Edge(to, cost));
        }

        public void AddUnDirectedEdge(int from, int to, int cost)
        {
            AddDirectedEdge(from, to, cost);
            AddDirectedEdge(to, from, cost);
        }
    }

#region Pair
    public class Pair<T>
    {
        public T First { get; set; }
        public T Second { get; set; }
        public Pair(T f, T s) { First = f; Second = s; }
        public override string ToString() { return "(" + First + ", " + Second + ")"; }
        public override int GetHashCode() { return First.GetHashCode() ^ Second.GetHashCode(); }
        public override bool Equals(object obj)
        {
            if (ReferenceEquals(this, obj)) return true;
            else if (obj == null) return false;
            var tmp = obj as Pair<T, T>;
            return (object)tmp != null && First.Equals(tmp.First) && Second.Equals(tmp.Second);
        }
    }

    public class Pair<T1, T2>
    {
        public T1 First;
        public T2 Second;
        public Pair() { First = default(T1); Second = default(T2); }
        public Pair(T1 f, T2 s) { First = f; Second = s; }
        public override string ToString() { return "(" + First + ", " + Second + ")"; }
        public override int GetHashCode() { return First.GetHashCode() ^ Second.GetHashCode(); }
        public override bool Equals(object obj)
        {
            if (ReferenceEquals(this, obj)) return true;
            else if (obj == null) return false;
            var tmp = obj as Pair<T1, T2>;
            return (object)tmp != null && First.Equals(tmp.First) && Second.Equals(tmp.Second);
        }
    }
#endregion

#region PriorityQueue
    public class PriorityQueue<T> : IEnumerable<T>, ICollection, IEnumerable
    {
        private Comparison<T> comp;
        private List<T> list;
        private int count;
        public int Count { get { return count; } }
        public bool IsEmpty { get { return count == 0; } }
        public PriorityQueue(IComparer<T> comp) : this((x, y) => comp.Compare(x, y)) { }
        public PriorityQueue(IComparer<T> comp, int capacity) : this((x, y) => comp.Compare(x, y), capacity) { }
        public PriorityQueue(IComparer<T> comp, IEnumerable<T> source) : this((x, y) => comp.Compare(x, y), source) { }
        public PriorityQueue(IComparer<T> comp, int capacity, IEnumerable<T> source) : this((x, y) => comp.Compare(x, y), source) { list.Capacity = capacity; }
        public PriorityQueue() : this((x, y) => ((IComparable<T>)x).CompareTo(y)) { }
        public PriorityQueue(int capacity) : this((x, y) => ((IComparable<T>)x).CompareTo(y), capacity) { }
        public PriorityQueue(IEnumerable<T> source) : this((x, y) => ((IComparable<T>)x).CompareTo(y), source) { }
        public PriorityQueue(int capacity, IEnumerable<T> source) : this((x, y) => ((IComparable<T>)x).CompareTo(y), source) { list.Capacity = capacity; }
        public PriorityQueue(Comparison<T> comparison)
        {
            comp = comparison;
            list = new List<T>();
            count = 0;
        }
        public PriorityQueue(Comparison<T> comparison, IEnumerable<T> source) : this(comparison) { foreach (var x in source) Enqueue(x); }
        public PriorityQueue(Comparison<T> comparison, int capacity) : this(comparison) { list.Capacity = capacity; }
        public void Enqueue(T x) // O(log n)
        {
            var pos = count++;
            list.Add(x);
            while (pos > 0)
            {
                var p = (pos - 1) / 2;
                if (comp(list[p], x) <= 0) break;
                list[pos] = list[p];
                pos = p;
            }
            list[pos] = x;
        }
        public T Dequeue() // O(log n)
        {
            if (count == 0) throw new InvalidOperationException();
            var value = list[0];
            var x = list[--count];
            list.RemoveAt(count);
            if (count == 0) return value;
            var pos = 0;
            while (pos * 2 + 1 < count)
            {
                var a = 2 * pos + 1;
                var b = 2 * pos + 2;
                if (b < count && comp(list[b], list[a]) < 0) a = b;
                if (comp(list[a], x) >= 0) break;
                list[pos] = list[a];
                pos = a;
            }
            list[pos] = x;
            return value;
        }
        public T Peek() { return list[0]; } // O(1)
        public void Clear() { list = new List<T>(); count = 0; } // O(1)
        public void TrimExcess() { list.TrimExcess(); } // O(1)
        public bool Contains(T item) { return list.Contains(item); } // O(n)
        void CopyTo(Array array, int index)
        {
            if (array == null)
                throw new ArgumentNullException();
            if (index < 0)
                throw new ArgumentOutOfRangeException();
            var tmp = new PriorityQueue<T>(comp, list.Count);
            for (var i = 0; i < count; i++) tmp.Enqueue(list[i]);
            while (!tmp.IsEmpty) array.SetValue(tmp.Dequeue(), index++);
        }
        bool ICollection.IsSynchronized { get { return false; } }
        object ICollection.SyncRoot { get { return this; } }
        public IEnumerator<T> GetEnumerator()
        {
            var tmp = new PriorityQueue<T>(comp, list.Count);
            for (var i = 0; i < count; i++) tmp.Enqueue(list[i]);
            while (!tmp.IsEmpty) yield return tmp.Dequeue();
        }
        IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
        void ICollection.CopyTo(Array array, int index) { CopyTo(array, index); }
        int ICollection.Count { get { return count; } }
        public bool Any() { return count > 0; }
    }
#endregion
}