Problem:
Score : 300 points

Problem Statement

We have a grid of H rows and W columns of squares. The color of the square at the i-th row from the top and the j-th column from the left (1 \leq i \leq H, 1 \leq j \leq W) is given to you as a character c_{i,j}: the square is white if c_{i,j} is ., and black if c_{i,j} is #.

Consider doing the following operation:

Choose some number of rows (possibly zero), and some number of columns (possibly zero). Then, paint red all squares in the chosen rows and all squares in the chosen columns.

You are given a positive integer K. How many choices of rows and columns result in exactly K black squares remaining after the operation? Here, we consider two choices different when there is a row or column chosen in only one of those choices.

Constraints

1 \leq H, W \leq 6

1 \leq K \leq HW

c_{i,j} is . or #.

Input

Input is given from Standard Input in the following format:

H W K
c_{1,1}c_{1,2}...c_{1,W}
c_{2,1}c_{2,2}...c_{2,W}
:
c_{H,1}c_{H,2}...c_{H,W}

Output

Print an integer representing the number of choices of rows and columns satisfying the condition.

Sample Input 1

2 3 2
..#
###

Sample Output 1

5

Five choices below satisfy the condition.

The 1-st row and 1-st column

The 1-st row and 2-nd column

The 1-st row and 3-rd column

The 1-st and 2-nd column

The 3-rd column

Sample Input 2

2 3 4
..#
###

Sample Output 2

1

One choice, which is choosing nothing, satisfies the condition.

Sample Input 3

2 2 3
##
##

Sample Output 3

0

Sample Input 4

6 6 8
..##..
.#..#.
#....#
######
#....#
#....#

Sample Output 4

208

Solution in C# (.NET Core 3.1.201) (judge verdict: Accepted)

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection.Metadata;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;

namespace ForATCODER
{
    public class Program
    {
        ///template
        ///
        /// String[] s = Console.ReadLine().Split(' ');
        ///   long[] nk =  s2larray(Console.ReadLine().Split(' '));
        ///  

        public static void Main(string[] args)
        {

            long[] hw = s2larray(Console.ReadLine().Split(' '));
            int[,] mas = new int[hw[0], hw[1]];
            int[] c1 = new int[hw[1]];
            int[] c2 = new int[hw[0]];
            int[,] cc = new int[hw[0], hw[1]];
            int count = 0;

            int[,] pat1 = new int[(int)Math.Pow(2, hw[1]), hw[1]];
            int[,] pat2 = new int[(int)Math.Pow(2, hw[0]), hw[0]];
            for (int x = 0; x < Math.Pow(2, hw[1]); x++)
            {
                var array = new bool[hw[1]];
                for (int k = 0; k < hw[1]; k++)
                {
                    var y = (x >> k) & 1;
                    pat1[x, k] = y;
                }
            }
            for (int x = 0; x < Math.Pow(2, hw[0]); x++)
            {
                var array = new bool[hw[0]];
                for (int k = 0; k < hw[0]; k++)
                {
                    var y = (x >> k) & 1;
                    pat2[x, k] = y;
                }
            }

            for (int i = 0; i < hw[0];i++)
            {
                string cw = Console.ReadLine();
                for(int j = 0; j < hw[1];j++)
                {
                    mas[i, j] = cw[j] == '.' ? 0 : 1;
                    if (cw[j] == '#') {
                        count++;
                        c2[i]++;
                        c1[j]++;
                    }
                }
            }
            int res = 0;
            int sum_=0;
            for (int x = 0; x < Math.Pow(2, hw[0]); x++)
            {
                int sum = 0;
                for (int k = 0; k < hw[0]; k++)
                {

                    if (pat2[x, k] == 1) { sum += c2[k];  }
                }
           //     if (sum > hw[2]) continue;
            //   RESULT("sum:"+sum);
                sum_ = sum;
                for (int y = 0; y < Math.Pow(2, hw[1]); y++)
                {
                    for (int l = 0; l < hw[1]; l++)
                    {
                        if (pat1[y, l] == 1) { sum += c1[l];
                            for (int k = 0; k < hw[0]; k++)
                            {

                                if (pat2[x, k] == 1 && mas[k, l] == 1) sum--;
                            }
                        }
                      
                    }
                    if (hw[2] == (count-sum)) { res++;

//RESULT(x + ","+y);
                    }
                  sum = sum_;
                }

      

                }
           //     int res = 0;
            //行列
         /*   for (int i = 0; i < hw[0]; i++)
            {
                int c1_ = c2[i];
                if(hw[2] - c1_==0)
                {
                    res++;
                    continue;
                }
                if (hw[2] - c1_ < 0) continue;
                c1_ = (int)hw[2] - c1_;
                    for (int j = 0; j < hw[1]; j++)
                {
                    int c2_ = c1[j];
                    if (mas[i,j] == 1) c2_--;
                    if (c2_ == c1_) res++;
                }
            }*/
        
            RESULT(res);


        }
        
      
        /// <summary>
        /// Original Tree Class
        /// </summary>
        /// <typeparam name="T"></typeparam>
        class TreeNode<T>
        {
            List<TreeNode<T>> Children;

            T Item { get; set; }

            public TreeNode(T item)
            {
                Item = item;
            }

            public TreeNode<T> AddChild(T item)
            {
                TreeNode<T> nodeItem = new TreeNode<T>(item);
                Children.Add(nodeItem);
                return nodeItem;
            }
            public void AddChildRelative(TreeNode<T> item)
            {
                Children.Add(item);
            }
            public List<TreeNode<T>> GetChildren(T val)
            {
                if (val.Equals(Item))
                {
                    var l = new List<TreeNode<T>>();
                    l.Add(this);
                    return l;
                }
                return Children.FindAll(x => x.Item.Equals(val));
            }
        }

        static void addarray(long[] arr, int start, int end)
        {
            for (int i = start; i <= end; i++)
            {
                arr[i]++;
            }
        }
        public static decimal Sqrt(decimal x)
        {
            decimal sqrt_x = (decimal)Math.Sqrt((long)x);
            for (int i = 0; i < 10; ++i)
                sqrt_x = 0.5m * (sqrt_x + x / sqrt_x);
            return sqrt_x;
        }
        static long summ(long s)
        {
            if (s == 1) return 1;
            return s + summ(s - 1);
        }
        public static bool checka(int[] a, int m)
        {
            int back = 1;
            for (int i = 0; i < a.Length; i++)
            {
                if (a[i] >= 1 && a[i] <= m)
                {
                    if (a[i] >= back)
                    {
                        back = a[i];
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
            return true;
        }
        public static ulong pow(int a, int b)
        {
            ulong res = 1;
            for (int i = 0; i < b; i++)
            {
                res *= (ulong)a;
            }
            return res;
        }
        static int s2i(String s)
        {
            return Convert.ToInt32(s);
        }
        static long s2l(String s)
        {
            return Convert.ToInt64(s);
        }
        static void RESULT(double res)
        {
            Console.WriteLine(res);
        }
        static void RESULT(long res)
        {
            Console.WriteLine(res);
        }
        static void RESULT(ulong res)
        {
            Console.WriteLine(res);
        }
        static void RESULT(int res)
        {
            Console.WriteLine(res);
        }
        static void RESULT(String res)
        {
            Console.WriteLine(res);
        }
        static String[] ReadLineAll(int count)
        {
            String[] res = new String[count];
            for (int i = 0; i < count; i++)
            {
                res[i] = Console.ReadLine();
            }
            return res;
        }

        static int[] s2iarray(String[] src)
        {
            int len = src.Length;
            int[] res = new int[len];
            for (int i = 0; i < len; i++)
            {
                res[i] = Convert.ToInt32(src[i]);
            }
            return res;
        }
        static long[] s2larray(String[] src)
        {
            int len = src.Length;
            long[] res = new long[len];
            for (int i = 0; i < len; i++)
            {
                res[i] = Convert.ToInt64(src[i]);
            }
            return res;
        }
        static decimal[] s2darray(String[] src)
        {
            int len = src.Length;
            decimal[] res = new decimal[len];
            for (int i = 0; i < len; i++)
            {
                res[i] = Convert.ToDecimal(src[i]);
            }
            return res;
        }
        static ulong[] s2larray2(String[] src)
        {
            int len = src.Length;
            ulong[] res = new ulong[len];
            for (int i = 0; i < len; i++)
            {
                res[i] = Convert.ToUInt64(src[i]);
            }
            return res;
        }

        static long C(int n, int r)
        {
            if (n <= 1) return 0;
            if (r > n - r) r = n - r; // because C(n, r) == C(n, n - r)
            long ans = 1;
            int i;

            for (i = 1; i <= r; i++)
            {
                ans *= n - r + i;
                ans /= i;
            }

            return ans;
        }
        static long C(long n, long r)
        {
            if (n <= 1) return 0;
            if (r > n - r) r = n - r; // because C(n, r) == C(n, n - r)
            long ans = 1;
            int i;

            for (i = 1; i <= r; i++)
            {
                ans *= n - r + i;
                ans /= i;
            }

            return ans;
        }
        static ulong C(ulong n, ulong r)
        {
            if (n <= 1) return 0;
            if (r > n - r) r = n - r; // because C(n, r) == C(n, n - r)
            ulong ans = 1;
            ulong i;

            for (i = 1; i <= r; i++)
            {
                ans *= n - r + i;
                ans /= i;
            }

            return ans;
        }


    }

}