// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to find the length of the
// smallest subarray to be removed such
// that sum of elements is equal to S % K
static int removeSmallestSubarray(int []arr, int S,
int n, int k)
{
// Remainder when total_sum
// is divided by K
int target_remainder = S % k;
// Stores curr_remainder and the
// most recent index at which
// curr_remainder has occurred
Dictionary<int,
int> map1 = new Dictionary<int,
int>();
map1.Add(0, -1);
int curr_remainder = 0;
// Stores required answer
int res = int.MaxValue;
for(int i = 0; i < n; i++)
{
// Add current element to
// curr_sum and take mod
curr_remainder = (curr_remainder +
arr[i] + k) % k;
// Update current
// remainder index
map1[curr_remainder]= i;
int mod = (curr_remainder -
target_remainder +
k) % k;
// If mod already exists in map
// the subarray exists
if (map1.ContainsKey(mod))
{
// Update res
res = Math.Min(res, i -
map1[mod]);
}
}
// If not possible
if (res == int.MaxValue ||
res == n)
{
res = -1;
}
// Return the result
return res;
}
// Function to find the smallest submatrix
// rqured to be deleted to make the sum
// of the matrix divisible by K
static int smstSubmatDeleted(int[,]mat,
int N, int M,
int K)
{
// Stores the sum of
// element of the matrix
int S = 0;
// Traverse the matrix [,]mat
for(int i = 0; i < N; i++)
{
for(int j = 0; j < M; j++)
// Update S
S += mat[i,j];
}
// Stores smallest area need
// to be deleted to get sum
// divisible by K
int min_area = N * M;
// Stores leftmost column
// of each matrix
int left = 0;
// Stores rightmost column
// of each matrix
int right = 0;
// Stores number of columns
// deleted of a matrix
int width;
// Store area of the deleted
// matrix
int area;
// prefixRowSum[i]: Store sum
// of sub matrix whose topmost
// left and bottommost right
// position is (0, left) (i, right)
int []prefixRowSum = new int[N];
// Iterate over all possible
// values of (left, right)
for(left = 0; left < M; left++)
{
// Initialize all possible
// values of prefixRowSum[]
// to 0
for(int i = 0; i < prefixRowSum.Length; i++)
prefixRowSum[i] = 0;
for(right = left;
right < M; right++)
{
// Traverse each row from
// left to right column
for(int i = 0; i < N; i++)
{
// Update row_sum[i];
prefixRowSum[i] += mat[i, right];
}
// Update width
width = removeSmallestSubarray(
prefixRowSum, S, N, K);
// If no submatrix of the
// length (right - left + 1)
// found to get the required
// output
if (width != -1)
{
// Update area
area = (right - left + 1) *
(width);
// If area is less than
// min_area
if (area < min_area)
{
// Update min_area
min_area = area;
}
}
}
}
return min_area;
}
// Driver Code
public static void Main(String[] args)
{
int[,] mat = { { 6, 2, 6 },
{ 3, 2, 8 },
{ 2, 5, 3 } };
int K = 3;
// Stores number of rows
// in the matrix
int N = mat.GetLength(0);
// Stores number of column
// in the matrix
int M = mat.GetLength(1);
Console.Write(
smstSubmatDeleted(mat, N,
M, K));
}
}
// This code is contributed by shikhasingrajput