给定一个二元矩阵M ,其中矩阵的每个元素都是 0 或 1,任务是找到可以与中心(i, j)形成且最多包含K 个1 的最大正方形。
Input: M[][] = {
{1, 0, 1, 0, 0}
{1, 0, 1, 1, 1}
{1, 1, 1, 1, 1}
{1, 0, 0, 1, 0}},
i = 1, j = 2, K = 9
Output: 3
Explanation:
Maximum length square with center at (1, 2)
that can be formed is of 3 length from (0, 1) to (2, 4)
Input: M[][] = {
{ 1, 1, 1 },
{ 1, 1, 1 },
{ 1, 1, 1 }},
i = 1, j = 1, K = 9
Output: 3
天真的方法:
对于每个查询,考虑所有以 (i, j) 为中心的正方形,并不断将正方形的长度从 1 增加到其最大可能值,直到正方形中 1 的计数小于 K。正方形的长度将为 2*MIN_DIST + 1,其中 MIN_DIST 是中心到矩阵边缘的最小距离。所以对于中心为 (i, j) 的 R*C 矩阵,
MIN_DIST = min( i, j, R-i-1, C-j-1 )
下面是上述方法的实现:
C++
// C++ implementation to find the
// largest square in the matrix such
// that it contains atmost K 1's
#include
using namespace std;
const int MAX = 100;
// Function to calculate the
// largest square with atmost K
// 1s for Q queries
void largestSquare(int matrix[][MAX],
int R, int C, int q_i[],
int q_j[], int K, int Q){
// Loop to solve for each query
for (int q = 0; q < Q; q++) {
int i = q_i[q];
int j = q_j[q];
int min_dist = min(min(i, j),
min(R - i - 1, C - j - 1));
int ans = -1;
for (int k = 0; k <= min_dist;
k++) {
int count = 0;
// Traversing the each sub
// square and counting total
for (int row = i - k;
row <= i + k; row++)
for (int col = j - k;
col <= j + k; col++)
count += matrix[row][col];
// Breaks when exceeds
// the maximum count
if (count > K)
break;
ans = 2 * k + 1;
}
cout << ans << "\n";
}
}
// Driver Code
int main()
{
int matrix[][MAX] = { { 1, 0, 1, 0, 0 },
{ 1, 0, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 0, 0, 1, 0 } };
int K = 9, Q = 1;
int q_i[] = { 1 };
int q_j[] = { 2 };
largestSquare(matrix, 4, 5, q_i,
q_j, K, Q);
return 0;
}
Java
// Java implementation to find the
// largest square in the matrix such
// that it contains atmost K 1's
class GFG{
static int MAX = 100;
// Function to calculate the
// largest square with atmost K
// 1s for Q queries
static void largestSquare(int matrix[][],
int R, int C,
int q_i[], int q_j[],
int K, int Q)
{
// Loop to solve for each query
for(int q = 0; q < Q; q++)
{
int i = q_i[q];
int j = q_j[q];
int min_dist = Math.min(Math.min(i, j),
Math.min(R - i - 1,
C - j - 1));
int ans = -1;
for(int k = 0; k <= min_dist; k++)
{
int count = 0;
// Traversing the each sub
// square and counting total
for(int row = i - k; row <= i + k; row++)
for(int col = j - k; col <= j + k; col++)
count += matrix[row][col];
// Breaks when exceeds
// the maximum count
if (count > K)
break;
ans = 2 * k + 1;
}
System.out.print(ans + "\n");
}
}
// Driver Code
public static void main(String[] args)
{
int matrix[][] = { { 1, 0, 1, 0, 0 },
{ 1, 0, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 0, 0, 1, 0 } };
int K = 9, Q = 1;
int q_i[] = { 1 };
int q_j[] = { 2 };
largestSquare(matrix, 4, 5, q_i, q_j, K, Q);
}
}
// This code is contributed by Amit Katiyar
Python3
# Python3 implementation to find the
# largest square in the matrix such
# that it contains at most K 1's
MAX = 100
# Function to calculate the
# largest square with atmost K
# 1s for Q queries
def largestSquare(matrix, R, C, q_i, q_j, K, Q):
# Loop to solve for each query
for q in range(Q):
i = q_i[q]
j = q_j[q]
min_dist = min(min(i, j),
min(R - i - 1, C - j - 1))
ans = -1
for k in range(min_dist + 1):
count = 0
# Traversing the each sub
# square and counting total
for row in range(i - k, i + k + 1):
for col in range(j - k, j + k + 1):
count += matrix[row][col]
# Breaks when exceeds
# the maximum count
if count > K:
break
ans = 2 * k + 1
print(ans)
# Driver Code
matrix = [ [ 1, 0, 1, 0, 0 ],
[ 1, 0, 1, 1, 1 ],
[ 1, 1, 1, 1, 1 ],
[ 1, 0, 0, 1, 0 ] ]
K = 9
Q = 1
q_i = [ 1 ]
q_j = [ 2 ]
largestSquare(matrix, 4, 5, q_i, q_j, K, Q)
# This code is contributed by divyamohan123
C#
// C# implementation to find the
// largest square in the matrix such
// that it contains atmost K 1's
using System;
class GFG{
//static int MAX = 100;
// Function to calculate the
// largest square with atmost K
// 1s for Q queries
static void largestSquare(int [,]matrix,
int R, int C,
int []q_i, int []q_j,
int K, int Q)
{
// Loop to solve for each query
for(int q = 0; q < Q; q++)
{
int i = q_i[q];
int j = q_j[q];
int min_dist = Math.Min(Math.Min(i, j),
Math.Min(R - i - 1,
C - j - 1));
int ans = -1;
for(int k = 0; k <= min_dist; k++)
{
int count = 0;
// Traversing the each sub
// square and counting total
for(int row = i - k; row <= i + k; row++)
for(int col = j - k; col <= j + k; col++)
count += matrix[row, col];
// Breaks when exceeds
// the maximum count
if (count > K)
break;
ans = 2 * k + 1;
}
Console.Write(ans + "\n");
}
}
// Driver Code
public static void Main(String[] args)
{
int [,]matrix = { { 1, 0, 1, 0, 0 },
{ 1, 0, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 0, 0, 1, 0 } };
int K = 9, Q = 1;
int []q_i = {1};
int []q_j = {2};
largestSquare(matrix, 4, 5, q_i, q_j, K, Q);
}
}
// This code is contributed by Amit Katiyar
Javascript
C++
// C++ implementation to find the
// largest square in the matrix such
// that it contains atmost K 1's
#include
using namespace std;
const int MAX = 100;
// Function to find the
// largest square in the matrix such
// that it contains atmost K 1's
void largestSquare(int matrix[][MAX],
int R, int C, int q_i[],
int q_j[], int K, int Q){
int countDP[R][C];
memset(countDP, 0, sizeof(countDP));
// Precomputing the countDP
// prefix sum of the matrix
countDP[0][0] = matrix[0][0];
for (int i = 1; i < R; i++)
countDP[i][0] = countDP[i - 1][0] +
matrix[i][0];
for (int j = 1; j < C; j++)
countDP[0][j] = countDP[0][j - 1] +
matrix[0][j];
for (int i = 1; i < R; i++)
for (int j = 1; j < C; j++)
countDP[i][j] = matrix[i][j] +
countDP[i - 1][j] +
countDP[i][j - 1] -
countDP[i - 1][j - 1];
// Loop to solve Queries
for (int q = 0; q < Q; q++) {
int i = q_i[q];
int j = q_j[q];
// Calculating the maximum
// possible distance of the
// centre from edge
int min_dist = min(min(i, j),
min(R - i - 1, C - j - 1));
int ans = -1;
for (int k = 0; k <= min_dist;
k++) {
int x1 = i - k, x2 = i + k;
int y1 = j - k, y2 = j + k;
// Calculating the number
// of 1s in the submatrix
int count = countDP[x2][y2];
if (x1 > 0)
count -= countDP[x1 - 1][y2];
if (y1 > 0)
count -= countDP[x2][y1 - 1];
if (x1 > 0 && y1 > 0)
count += countDP[x1 - 1][y1 - 1];
if (count > K)
break;
ans = 2 * k + 1;
}
cout << ans << "\n";
}
}
// Driver Code
int main()
{
int matrix[][MAX] = { { 1, 0, 1, 0, 0 },
{ 1, 0, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 0, 0, 1, 0 } };
int K = 9, Q = 1;
int q_i[] = { 1 };
int q_j[] = { 2 };
largestSquare(matrix, 4, 5, q_i,
q_j, K, Q);
return 0;
}
Java
// Java implementation to find the
// largest square in the matrix such
// that it contains atmost K 1's
import java.util.*;
class GFG{
static int MAX = 100;
// Function to find the
// largest square in the matrix such
// that it contains atmost K 1's
static void largestSquare(int matrix[][], int R,
int C, int q_i[],
int q_j[], int K,
int Q)
{
int [][]countDP = new int[R][C];
// Precomputing the countDP
// prefix sum of the matrix
countDP[0][0] = matrix[0][0];
for(int i = 1; i < R; i++)
countDP[i][0] = countDP[i - 1][0] +
matrix[i][0];
for(int j = 1; j < C; j++)
countDP[0][j] = countDP[0][j - 1] +
matrix[0][j];
for(int i = 1; i < R; i++)
for(int j = 1; j < C; j++)
countDP[i][j] = matrix[i][j] +
countDP[i - 1][j] +
countDP[i][j - 1] -
countDP[i - 1][j - 1];
// Loop to solve Queries
for(int q = 0; q < Q; q++)
{
int i = q_i[q];
int j = q_j[q];
// Calculating the maximum
// possible distance of the
// centre from edge
int min_dist = Math.min(Math.min(i, j),
Math.min(R - i - 1,
C - j - 1));
int ans = -1;
for(int k = 0; k <= min_dist; k++)
{
int x1 = i - k, x2 = i + k;
int y1 = j - k, y2 = j + k;
// Calculating the number
// of 1s in the submatrix
int count = countDP[x2][y2];
if (x1 > 0)
count -= countDP[x1 - 1][y2];
if (y1 > 0)
count -= countDP[x2][y1 - 1];
if (x1 > 0 && y1 > 0)
count += countDP[x1 - 1][y1 - 1];
if (count > K)
break;
ans = 2 * k + 1;
}
System.out.print(ans + "\n");
}
}
// Driver Code
public static void main(String[] args)
{
int matrix[][] = { { 1, 0, 1, 0, 0 },
{ 1, 0, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 0, 0, 1, 0 } };
int K = 9, Q = 1;
int q_i[] = { 1 };
int q_j[] = { 2 };
largestSquare(matrix, 4, 5, q_i,
q_j, K, Q);
}
}
// This code is contributed by gauravrajput1
Python3
# Python3 implementation to find the
# largest square in the matrix such
# that it contains atmost K 1's
# Function to find the largest
# square in the matrix such
# that it contains atmost K 1's
def largestSquare(matrix, R, C, q_i,
q_j, K, Q):
countDP = [[0 for x in range(C)]
for x in range(R)]
# Precomputing the countDP
# prefix sum of the matrix
countDP[0][0] = matrix[0][0]
for i in range(1, R):
countDP[i][0] = (countDP[i - 1][0] +
matrix[i][0])
for j in range(1, C):
countDP[0][j] = (countDP[0][j - 1] +
matrix[0][j])
for i in range(1, R):
for j in range(1, C):
countDP[i][j] = (matrix[i][j] +
countDP[i - 1][j] +
countDP[i][j - 1] -
countDP[i - 1][j - 1])
# Loop to solve Queries
for q in range(0, Q):
i = q_i[q]
j = q_j[q]
# Calculating the maximum
# possible distance of the
# centre from edge
min_dist = min(i, j, R - i - 1,
C - j - 1)
ans = -1
for k in range(0, min_dist + 1):
x1 = i - k
x2 = i + k
y1 = j - k
y2 = j + k
# Calculating the number
# of 1s in the submatrix
count = countDP[x2][y2];
if (x1 > 0):
count -= countDP[x1 - 1][y2]
if (y1 > 0):
count -= countDP[x2][y1 - 1]
if (x1 > 0 and y1 > 0):
count += countDP[x1 - 1][y1 - 1]
if (count > K):
break
ans = 2 * k + 1
print(ans)
# Driver Code
matrix = [ [ 1, 0, 1, 0, 0 ],
[ 1, 0, 1, 1, 1 ],
[ 1, 1, 1, 1, 1 ],
[ 1, 0, 0, 1, 0 ] ]
K = 9
Q = 1
q_i = [1]
q_j = [2]
largestSquare(matrix, 4, 5, q_i, q_j, K, Q)
# This code is contributed by Stream_Cipher
C#
// C# implementation to find the
// largest square in the matrix such
// that it contains atmost K 1's
using System;
class GFG{
//static int MAX = 100;
// Function to find the
// largest square in the matrix such
// that it contains atmost K 1's
static void largestSquare(int [,]matrix, int R,
int C, int []q_i,
int []q_j, int K,
int Q)
{
int [,]countDP = new int[R, C];
// Precomputing the countDP
// prefix sum of the matrix
countDP[0, 0] = matrix[0, 0];
for(int i = 1; i < R; i++)
countDP[i, 0] = countDP[i - 1, 0] +
matrix[i, 0];
for(int j = 1; j < C; j++)
countDP[0, j] = countDP[0, j - 1] +
matrix[0, j];
for(int i = 1; i < R; i++)
for(int j = 1; j < C; j++)
countDP[i, j] = matrix[i, j] +
countDP[i - 1, j] +
countDP[i, j - 1] -
countDP[i - 1, j - 1];
// Loop to solve Queries
for(int q = 0; q < Q; q++)
{
int i = q_i[q];
int j = q_j[q];
// Calculating the maximum
// possible distance of the
// centre from edge
int min_dist = Math.Min(Math.Min(i, j),
Math.Min(R - i - 1,
C - j - 1));
int ans = -1;
for(int k = 0; k <= min_dist; k++)
{
int x1 = i - k, x2 = i + k;
int y1 = j - k, y2 = j + k;
// Calculating the number
// of 1s in the submatrix
int count = countDP[x2, y2];
if (x1 > 0)
count -= countDP[x1 - 1, y2];
if (y1 > 0)
count -= countDP[x2, y1 - 1];
if (x1 > 0 && y1 > 0)
count += countDP[x1 - 1, y1 - 1];
if (count > K)
break;
ans = 2 * k + 1;
}
Console.Write(ans + "\n");
}
}
// Driver Code
public static void Main(String[] args)
{
int [,]matrix = { { 1, 0, 1, 0, 0 },
{ 1, 0, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 0, 0, 1, 0 } };
int K = 9, Q = 1;
int []q_i = { 1 };
int []q_j = { 2 };
largestSquare(matrix, 4, 5, q_i,
q_j, K, Q);
}
}
// This code is contributed by princi singh
Javascript
C++
// C++ implementation to find the
// largest square in the matrix such
// that it contains atmost K 1's
#include
using namespace std;
const int MAX = 100;
// Function to find the
// largest square in the matrix such
// that it contains atmost K 1's
void largestSquare(int matrix[][MAX],
int R, int C, int q_i[],
int q_j[], int K, int Q){
int countDP[R][C];
memset(countDP, 0, sizeof(countDP));
// Precomputation of the countDP
// prefix sum of the matrix
countDP[0][0] = matrix[0][0];
for (int i = 1; i < R; i++)
countDP[i][0] = countDP[i - 1][0] +
matrix[i][0];
for (int j = 1; j < C; j++)
countDP[0][j] = countDP[0][j - 1] +
matrix[0][j];
for (int i = 1; i < R; i++)
for (int j = 1; j < C; j++)
countDP[i][j] = matrix[i][j] +
countDP[i - 1][j] +
countDP[i][j - 1] -
countDP[i - 1][j - 1];
// Loop to solve each query
for (int q = 0; q < Q; q++) {
int i = q_i[q];
int j = q_j[q];
int min_dist = min(min(i, j),
min(R - i - 1, C - j - 1));
int ans = -1, l = 0, u = min_dist;
// Binary Search to the side which
// have atmost in K 1's in square
while (l <= u) {
int mid = (l + u) / 2;
int x1 = i - mid, x2 = i + mid;
int y1 = j - mid, y2 = j + mid;
// Count total number of 1s in
// the sub square considered
int count = countDP[x2][y2];
if (x1 > 0)
count -= countDP[x1 - 1][y2];
if (y1 > 0)
count -= countDP[x2][y1 - 1];
if (x1 > 0 && y1 > 0)
count += countDP[x1 - 1][y1 - 1];
// If the count is less than or
// equals to the maximum move
// to right half
if (count <= K) {
ans = 2 * mid + 1;
l = mid + 1;
}
else
u = mid - 1;
}
cout << ans << "\n";
}
}
int main()
{
int matrix[][MAX] = { { 1, 0, 1, 0, 0 },
{ 1, 0, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 0, 0, 1, 0 } };
int K = 9, Q = 1;
int q_i[] = { 1 };
int q_j[] = { 2 };
largestSquare(matrix, 4, 5,
q_i, q_j, K, Q);
return 0;
}
Java
// Java implementation to find the
// largest square in the matrix such
// that it contains atmost K 1's
import java.util.*;
class GFG{
// Function to find the
// largest square in the matrix such
// that it contains atmost K 1's
static void largestSquare(int matrix[][], int R,
int C, int q_i[],
int q_j[], int K, int Q)
{
int countDP[][] = new int[R][C];
for(int i = 0; i < R; i++)
for(int j = 0; j < C; j++)
countDP[i][j] = 0;
// Precomputation of the countDP
// prefix sum of the matrix
countDP[0][0] = matrix[0][0];
for(int i = 1; i < R; i++)
countDP[i][0] = countDP[i - 1][0] +
matrix[i][0];
for(int j = 1; j < C; j++)
countDP[0][j] = countDP[0][j - 1] +
matrix[0][j];
for(int i = 1; i < R; i++)
for(int j = 1; j < C; j++)
countDP[i][j] = matrix[i][j] +
countDP[i - 1][j] +
countDP[i][j - 1] -
countDP[i - 1][j - 1];
// Loop to solve each query
for(int q = 0; q < Q; q++)
{
int i = q_i[q];
int j = q_j[q];
int min_dist = Math.min(Math.min(i, j),
Math.min(R - i - 1,
C - j - 1));
int ans = -1, l = 0, u = min_dist;
// Binary Search to the side which
// have atmost in K 1's in square
while (l <= u)
{
int mid = (l + u) / 2;
int x1 = i - mid, x2 = i + mid;
int y1 = j - mid, y2 = j + mid;
// Count total number of 1s in
// the sub square considered
int count = countDP[x2][y2];
if (x1 > 0)
count -= countDP[x1 - 1][y2];
if (y1 > 0)
count -= countDP[x2][y1 - 1];
if (x1 > 0 && y1 > 0)
count += countDP[x1 - 1][y1 - 1];
// If the count is less than or
// equals to the maximum move
// to right half
if (count <= K)
{
ans = 2 * mid + 1;
l = mid + 1;
}
else
u = mid - 1;
}
System.out.println(ans);
}
}
// Driver code
public static void main(String args[])
{
int matrix[][] = { { 1, 0, 1, 0, 0 },
{ 1, 0, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 0, 0, 1, 0 } };
int K = 9, Q = 1;
int q_i[] = {1};
int q_j[] = {2};
largestSquare(matrix, 4, 5, q_i, q_j, K, Q);
}
}
// This code is contributed by Stream_Cipher
Python3
# Python3 implementation to find the
# largest square in the matrix such
# that it contains atmost K 1's
# Function to find the
# largest square in the matrix such
# that it contains atmost K 1's
def largestSquare(matrix, R, C, q_i,
q_j, K, Q):
countDP = [[0 for x in range(C)]
for x in range(R)]
# Precomputing the countDP
# prefix sum of the matrix
countDP[0][0] = matrix[0][0]
for i in range(1, R):
countDP[i][0] = (countDP[i - 1][0] +
matrix[i][0])
for j in range(1, C):
countDP[0][j] = (countDP[0][j - 1] +
matrix[0][j])
for i in range(1, R):
for j in range(1, C):
countDP[i][j] = (matrix[i][j] +
countDP[i - 1][j] +
countDP[i][j - 1] -
countDP[i - 1][j - 1])
# Loop to solve Queries
for q in range(0,Q):
i = q_i[q]
j = q_j[q]
# Calculating the maximum
# possible distance of the
# centre from edge
min_dist = min(i, j, R - i - 1,
C - j - 1)
ans = -1
l = 0
u = min_dist
while (l <= u):
mid = int((l + u) / 2)
x1 = i - mid
x2 = i + mid
y1 = j - mid
y2 = j + mid
# Count total number of 1s in
# the sub square considered
count = countDP[x2][y2]
if (x1 > 0):
count -= countDP[x1 - 1][y2]
if (y1 > 0):
count -= countDP[x2][y1 - 1]
if (x1 > 0 and y1 > 0):
count += countDP[x1 - 1][y1 - 1]
# If the count is less than or
# equals to the maximum move
# to right half
if (count <= K):
ans = 2 * mid + 1
l = mid + 1
else:
u = mid - 1
print(ans)
# Driver Code
matrix = [ [ 1, 0, 1, 0, 0 ],
[ 1, 0, 1, 1, 1 ],
[ 1, 1, 1, 1, 1 ],
[ 1, 0, 0, 1, 0 ] ]
K = 9
Q = 1
q_i = [1]
q_j = [2]
largestSquare(matrix, 4, 5, q_i, q_j, K, Q)
# This code is contributed by Stream_Cipher
C#
// C# implementation to find the
// largest square in the matrix such
// that it contains atmost K 1's
using System.Collections.Generic;
using System;
class GFG{
// Function to find the largest
// square in the matrix such
// that it contains atmost K 1's
static void largestSquare(int [,]matrix, int R,
int C, int []q_i,
int []q_j, int K, int Q)
{
int [,]countDP = new int[R, C];
for(int i = 0; i < R; i++)
for(int j = 0; j < C; j++)
countDP[i, j]=0;
// Precomputation of the countDP
// prefix sum of the matrix
countDP[0, 0] = matrix[0, 0];
for(int i = 1; i < R; i++)
countDP[i, 0] = countDP[i - 1, 0] +
matrix[i, 0];
for(int j = 1; j < C; j++)
countDP[0, j] = countDP[0, j - 1] +
matrix[0, j];
for(int i = 1; i < R; i++)
for(int j = 1; j < C; j++)
countDP[i, j] = matrix[i, j] +
countDP[i - 1, j] +
countDP[i, j - 1] -
countDP[i - 1, j - 1];
// Loop to solve each query
for(int q = 0; q < Q; q++)
{
int i = q_i[q];
int j = q_j[q];
int min_dist = Math.Min(Math.Min(i, j),
Math.Min(R - i - 1,
C - j - 1));
int ans = -1, l = 0, u = min_dist;
// Binary Search to the side which
// have atmost in K 1's in square
while (l <= u)
{
int mid = (l + u) / 2;
int x1 = i - mid, x2 = i + mid;
int y1 = j - mid, y2 = j + mid;
// Count total number of 1s in
// the sub square considered
int count = countDP[x2, y2];
if (x1 > 0)
count -= countDP[x1 - 1, y2];
if (y1 > 0)
count -= countDP[x2, y1 - 1];
if (x1 > 0 && y1 > 0)
count += countDP[x1 - 1, y1 - 1];
// If the count is less than or
// equals to the maximum move
// to right half
if (count <= K)
{
ans = 2 * mid + 1;
l = mid + 1;
}
else
u = mid - 1;
}
Console.WriteLine(ans);
}
}
// Driver code
public static void Main()
{
int [,]matrix = { { 1, 0, 1, 0, 0 },
{ 1, 0, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 0, 0, 1, 0 } };
int K = 9, Q = 1;
int []q_i = { 1 };
int []q_j = { 2 };
largestSquare(matrix, 4, 5,
q_i, q_j, K, Q);
}
}
// This code is contributed by Stream_Cipher
Javascript
输出 :
3
给定解决方案的最坏情况时间复杂度为O(Q*N*N*MIN_DIST) ,其中 N 是正方形的长度(最大为 2*MIN_DIST + 1)。
使用动态规划的有效方法:
这个想法是使用动态规划来计算每个正方形中 1 的数量,然后将长度增加 1 直到限制,然后最后检查 1 的计数是否小于 K。如果是,则更新答案。
要计算从 (x1, y1) 到 (x2, y2) 的子矩阵中 1 的数量,请使用:
Number of 1's = sumDP[x2][y2] - sumDP[x2][y1-1] -
sumDP[x1-1][y2] + sumDP[x1-1][y1-1]
下面是上述方法的实现:
C++
// C++ implementation to find the
// largest square in the matrix such
// that it contains atmost K 1's
#include
using namespace std;
const int MAX = 100;
// Function to find the
// largest square in the matrix such
// that it contains atmost K 1's
void largestSquare(int matrix[][MAX],
int R, int C, int q_i[],
int q_j[], int K, int Q){
int countDP[R][C];
memset(countDP, 0, sizeof(countDP));
// Precomputing the countDP
// prefix sum of the matrix
countDP[0][0] = matrix[0][0];
for (int i = 1; i < R; i++)
countDP[i][0] = countDP[i - 1][0] +
matrix[i][0];
for (int j = 1; j < C; j++)
countDP[0][j] = countDP[0][j - 1] +
matrix[0][j];
for (int i = 1; i < R; i++)
for (int j = 1; j < C; j++)
countDP[i][j] = matrix[i][j] +
countDP[i - 1][j] +
countDP[i][j - 1] -
countDP[i - 1][j - 1];
// Loop to solve Queries
for (int q = 0; q < Q; q++) {
int i = q_i[q];
int j = q_j[q];
// Calculating the maximum
// possible distance of the
// centre from edge
int min_dist = min(min(i, j),
min(R - i - 1, C - j - 1));
int ans = -1;
for (int k = 0; k <= min_dist;
k++) {
int x1 = i - k, x2 = i + k;
int y1 = j - k, y2 = j + k;
// Calculating the number
// of 1s in the submatrix
int count = countDP[x2][y2];
if (x1 > 0)
count -= countDP[x1 - 1][y2];
if (y1 > 0)
count -= countDP[x2][y1 - 1];
if (x1 > 0 && y1 > 0)
count += countDP[x1 - 1][y1 - 1];
if (count > K)
break;
ans = 2 * k + 1;
}
cout << ans << "\n";
}
}
// Driver Code
int main()
{
int matrix[][MAX] = { { 1, 0, 1, 0, 0 },
{ 1, 0, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 0, 0, 1, 0 } };
int K = 9, Q = 1;
int q_i[] = { 1 };
int q_j[] = { 2 };
largestSquare(matrix, 4, 5, q_i,
q_j, K, Q);
return 0;
}
Java
// Java implementation to find the
// largest square in the matrix such
// that it contains atmost K 1's
import java.util.*;
class GFG{
static int MAX = 100;
// Function to find the
// largest square in the matrix such
// that it contains atmost K 1's
static void largestSquare(int matrix[][], int R,
int C, int q_i[],
int q_j[], int K,
int Q)
{
int [][]countDP = new int[R][C];
// Precomputing the countDP
// prefix sum of the matrix
countDP[0][0] = matrix[0][0];
for(int i = 1; i < R; i++)
countDP[i][0] = countDP[i - 1][0] +
matrix[i][0];
for(int j = 1; j < C; j++)
countDP[0][j] = countDP[0][j - 1] +
matrix[0][j];
for(int i = 1; i < R; i++)
for(int j = 1; j < C; j++)
countDP[i][j] = matrix[i][j] +
countDP[i - 1][j] +
countDP[i][j - 1] -
countDP[i - 1][j - 1];
// Loop to solve Queries
for(int q = 0; q < Q; q++)
{
int i = q_i[q];
int j = q_j[q];
// Calculating the maximum
// possible distance of the
// centre from edge
int min_dist = Math.min(Math.min(i, j),
Math.min(R - i - 1,
C - j - 1));
int ans = -1;
for(int k = 0; k <= min_dist; k++)
{
int x1 = i - k, x2 = i + k;
int y1 = j - k, y2 = j + k;
// Calculating the number
// of 1s in the submatrix
int count = countDP[x2][y2];
if (x1 > 0)
count -= countDP[x1 - 1][y2];
if (y1 > 0)
count -= countDP[x2][y1 - 1];
if (x1 > 0 && y1 > 0)
count += countDP[x1 - 1][y1 - 1];
if (count > K)
break;
ans = 2 * k + 1;
}
System.out.print(ans + "\n");
}
}
// Driver Code
public static void main(String[] args)
{
int matrix[][] = { { 1, 0, 1, 0, 0 },
{ 1, 0, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 0, 0, 1, 0 } };
int K = 9, Q = 1;
int q_i[] = { 1 };
int q_j[] = { 2 };
largestSquare(matrix, 4, 5, q_i,
q_j, K, Q);
}
}
// This code is contributed by gauravrajput1
蟒蛇3
# Python3 implementation to find the
# largest square in the matrix such
# that it contains atmost K 1's
# Function to find the largest
# square in the matrix such
# that it contains atmost K 1's
def largestSquare(matrix, R, C, q_i,
q_j, K, Q):
countDP = [[0 for x in range(C)]
for x in range(R)]
# Precomputing the countDP
# prefix sum of the matrix
countDP[0][0] = matrix[0][0]
for i in range(1, R):
countDP[i][0] = (countDP[i - 1][0] +
matrix[i][0])
for j in range(1, C):
countDP[0][j] = (countDP[0][j - 1] +
matrix[0][j])
for i in range(1, R):
for j in range(1, C):
countDP[i][j] = (matrix[i][j] +
countDP[i - 1][j] +
countDP[i][j - 1] -
countDP[i - 1][j - 1])
# Loop to solve Queries
for q in range(0, Q):
i = q_i[q]
j = q_j[q]
# Calculating the maximum
# possible distance of the
# centre from edge
min_dist = min(i, j, R - i - 1,
C - j - 1)
ans = -1
for k in range(0, min_dist + 1):
x1 = i - k
x2 = i + k
y1 = j - k
y2 = j + k
# Calculating the number
# of 1s in the submatrix
count = countDP[x2][y2];
if (x1 > 0):
count -= countDP[x1 - 1][y2]
if (y1 > 0):
count -= countDP[x2][y1 - 1]
if (x1 > 0 and y1 > 0):
count += countDP[x1 - 1][y1 - 1]
if (count > K):
break
ans = 2 * k + 1
print(ans)
# Driver Code
matrix = [ [ 1, 0, 1, 0, 0 ],
[ 1, 0, 1, 1, 1 ],
[ 1, 1, 1, 1, 1 ],
[ 1, 0, 0, 1, 0 ] ]
K = 9
Q = 1
q_i = [1]
q_j = [2]
largestSquare(matrix, 4, 5, q_i, q_j, K, Q)
# This code is contributed by Stream_Cipher
C#
// C# implementation to find the
// largest square in the matrix such
// that it contains atmost K 1's
using System;
class GFG{
//static int MAX = 100;
// Function to find the
// largest square in the matrix such
// that it contains atmost K 1's
static void largestSquare(int [,]matrix, int R,
int C, int []q_i,
int []q_j, int K,
int Q)
{
int [,]countDP = new int[R, C];
// Precomputing the countDP
// prefix sum of the matrix
countDP[0, 0] = matrix[0, 0];
for(int i = 1; i < R; i++)
countDP[i, 0] = countDP[i - 1, 0] +
matrix[i, 0];
for(int j = 1; j < C; j++)
countDP[0, j] = countDP[0, j - 1] +
matrix[0, j];
for(int i = 1; i < R; i++)
for(int j = 1; j < C; j++)
countDP[i, j] = matrix[i, j] +
countDP[i - 1, j] +
countDP[i, j - 1] -
countDP[i - 1, j - 1];
// Loop to solve Queries
for(int q = 0; q < Q; q++)
{
int i = q_i[q];
int j = q_j[q];
// Calculating the maximum
// possible distance of the
// centre from edge
int min_dist = Math.Min(Math.Min(i, j),
Math.Min(R - i - 1,
C - j - 1));
int ans = -1;
for(int k = 0; k <= min_dist; k++)
{
int x1 = i - k, x2 = i + k;
int y1 = j - k, y2 = j + k;
// Calculating the number
// of 1s in the submatrix
int count = countDP[x2, y2];
if (x1 > 0)
count -= countDP[x1 - 1, y2];
if (y1 > 0)
count -= countDP[x2, y1 - 1];
if (x1 > 0 && y1 > 0)
count += countDP[x1 - 1, y1 - 1];
if (count > K)
break;
ans = 2 * k + 1;
}
Console.Write(ans + "\n");
}
}
// Driver Code
public static void Main(String[] args)
{
int [,]matrix = { { 1, 0, 1, 0, 0 },
{ 1, 0, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 0, 0, 1, 0 } };
int K = 9, Q = 1;
int []q_i = { 1 };
int []q_j = { 2 };
largestSquare(matrix, 4, 5, q_i,
q_j, K, Q);
}
}
// This code is contributed by princi singh
Javascript
输出 :
3
给定解决方案的最坏情况时间复杂度为O(R*C + Q*MIN_DIST) ,其中 R、C 是初始矩阵的维度。
使用动态规划和二分搜索的有效方法:
这个想法是使用二元搜索来找到最大的正方形,而不是迭代地增加边的长度并向最多给出 K 1 的边收敛。
二分搜索的搜索空间将是-
// Minimum possible answer will be
// the square with side 0
l = 0
// Maximum possible will be to include
// the whole square possible from (i, j)
r = min(min(i, j),
min(R - i - 1, C - i - 1))
下面是上述方法的实现:
C++
// C++ implementation to find the
// largest square in the matrix such
// that it contains atmost K 1's
#include
using namespace std;
const int MAX = 100;
// Function to find the
// largest square in the matrix such
// that it contains atmost K 1's
void largestSquare(int matrix[][MAX],
int R, int C, int q_i[],
int q_j[], int K, int Q){
int countDP[R][C];
memset(countDP, 0, sizeof(countDP));
// Precomputation of the countDP
// prefix sum of the matrix
countDP[0][0] = matrix[0][0];
for (int i = 1; i < R; i++)
countDP[i][0] = countDP[i - 1][0] +
matrix[i][0];
for (int j = 1; j < C; j++)
countDP[0][j] = countDP[0][j - 1] +
matrix[0][j];
for (int i = 1; i < R; i++)
for (int j = 1; j < C; j++)
countDP[i][j] = matrix[i][j] +
countDP[i - 1][j] +
countDP[i][j - 1] -
countDP[i - 1][j - 1];
// Loop to solve each query
for (int q = 0; q < Q; q++) {
int i = q_i[q];
int j = q_j[q];
int min_dist = min(min(i, j),
min(R - i - 1, C - j - 1));
int ans = -1, l = 0, u = min_dist;
// Binary Search to the side which
// have atmost in K 1's in square
while (l <= u) {
int mid = (l + u) / 2;
int x1 = i - mid, x2 = i + mid;
int y1 = j - mid, y2 = j + mid;
// Count total number of 1s in
// the sub square considered
int count = countDP[x2][y2];
if (x1 > 0)
count -= countDP[x1 - 1][y2];
if (y1 > 0)
count -= countDP[x2][y1 - 1];
if (x1 > 0 && y1 > 0)
count += countDP[x1 - 1][y1 - 1];
// If the count is less than or
// equals to the maximum move
// to right half
if (count <= K) {
ans = 2 * mid + 1;
l = mid + 1;
}
else
u = mid - 1;
}
cout << ans << "\n";
}
}
int main()
{
int matrix[][MAX] = { { 1, 0, 1, 0, 0 },
{ 1, 0, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 0, 0, 1, 0 } };
int K = 9, Q = 1;
int q_i[] = { 1 };
int q_j[] = { 2 };
largestSquare(matrix, 4, 5,
q_i, q_j, K, Q);
return 0;
}
Java
// Java implementation to find the
// largest square in the matrix such
// that it contains atmost K 1's
import java.util.*;
class GFG{
// Function to find the
// largest square in the matrix such
// that it contains atmost K 1's
static void largestSquare(int matrix[][], int R,
int C, int q_i[],
int q_j[], int K, int Q)
{
int countDP[][] = new int[R][C];
for(int i = 0; i < R; i++)
for(int j = 0; j < C; j++)
countDP[i][j] = 0;
// Precomputation of the countDP
// prefix sum of the matrix
countDP[0][0] = matrix[0][0];
for(int i = 1; i < R; i++)
countDP[i][0] = countDP[i - 1][0] +
matrix[i][0];
for(int j = 1; j < C; j++)
countDP[0][j] = countDP[0][j - 1] +
matrix[0][j];
for(int i = 1; i < R; i++)
for(int j = 1; j < C; j++)
countDP[i][j] = matrix[i][j] +
countDP[i - 1][j] +
countDP[i][j - 1] -
countDP[i - 1][j - 1];
// Loop to solve each query
for(int q = 0; q < Q; q++)
{
int i = q_i[q];
int j = q_j[q];
int min_dist = Math.min(Math.min(i, j),
Math.min(R - i - 1,
C - j - 1));
int ans = -1, l = 0, u = min_dist;
// Binary Search to the side which
// have atmost in K 1's in square
while (l <= u)
{
int mid = (l + u) / 2;
int x1 = i - mid, x2 = i + mid;
int y1 = j - mid, y2 = j + mid;
// Count total number of 1s in
// the sub square considered
int count = countDP[x2][y2];
if (x1 > 0)
count -= countDP[x1 - 1][y2];
if (y1 > 0)
count -= countDP[x2][y1 - 1];
if (x1 > 0 && y1 > 0)
count += countDP[x1 - 1][y1 - 1];
// If the count is less than or
// equals to the maximum move
// to right half
if (count <= K)
{
ans = 2 * mid + 1;
l = mid + 1;
}
else
u = mid - 1;
}
System.out.println(ans);
}
}
// Driver code
public static void main(String args[])
{
int matrix[][] = { { 1, 0, 1, 0, 0 },
{ 1, 0, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 0, 0, 1, 0 } };
int K = 9, Q = 1;
int q_i[] = {1};
int q_j[] = {2};
largestSquare(matrix, 4, 5, q_i, q_j, K, Q);
}
}
// This code is contributed by Stream_Cipher
蟒蛇3
# Python3 implementation to find the
# largest square in the matrix such
# that it contains atmost K 1's
# Function to find the
# largest square in the matrix such
# that it contains atmost K 1's
def largestSquare(matrix, R, C, q_i,
q_j, K, Q):
countDP = [[0 for x in range(C)]
for x in range(R)]
# Precomputing the countDP
# prefix sum of the matrix
countDP[0][0] = matrix[0][0]
for i in range(1, R):
countDP[i][0] = (countDP[i - 1][0] +
matrix[i][0])
for j in range(1, C):
countDP[0][j] = (countDP[0][j - 1] +
matrix[0][j])
for i in range(1, R):
for j in range(1, C):
countDP[i][j] = (matrix[i][j] +
countDP[i - 1][j] +
countDP[i][j - 1] -
countDP[i - 1][j - 1])
# Loop to solve Queries
for q in range(0,Q):
i = q_i[q]
j = q_j[q]
# Calculating the maximum
# possible distance of the
# centre from edge
min_dist = min(i, j, R - i - 1,
C - j - 1)
ans = -1
l = 0
u = min_dist
while (l <= u):
mid = int((l + u) / 2)
x1 = i - mid
x2 = i + mid
y1 = j - mid
y2 = j + mid
# Count total number of 1s in
# the sub square considered
count = countDP[x2][y2]
if (x1 > 0):
count -= countDP[x1 - 1][y2]
if (y1 > 0):
count -= countDP[x2][y1 - 1]
if (x1 > 0 and y1 > 0):
count += countDP[x1 - 1][y1 - 1]
# If the count is less than or
# equals to the maximum move
# to right half
if (count <= K):
ans = 2 * mid + 1
l = mid + 1
else:
u = mid - 1
print(ans)
# Driver Code
matrix = [ [ 1, 0, 1, 0, 0 ],
[ 1, 0, 1, 1, 1 ],
[ 1, 1, 1, 1, 1 ],
[ 1, 0, 0, 1, 0 ] ]
K = 9
Q = 1
q_i = [1]
q_j = [2]
largestSquare(matrix, 4, 5, q_i, q_j, K, Q)
# This code is contributed by Stream_Cipher
C#
// C# implementation to find the
// largest square in the matrix such
// that it contains atmost K 1's
using System.Collections.Generic;
using System;
class GFG{
// Function to find the largest
// square in the matrix such
// that it contains atmost K 1's
static void largestSquare(int [,]matrix, int R,
int C, int []q_i,
int []q_j, int K, int Q)
{
int [,]countDP = new int[R, C];
for(int i = 0; i < R; i++)
for(int j = 0; j < C; j++)
countDP[i, j]=0;
// Precomputation of the countDP
// prefix sum of the matrix
countDP[0, 0] = matrix[0, 0];
for(int i = 1; i < R; i++)
countDP[i, 0] = countDP[i - 1, 0] +
matrix[i, 0];
for(int j = 1; j < C; j++)
countDP[0, j] = countDP[0, j - 1] +
matrix[0, j];
for(int i = 1; i < R; i++)
for(int j = 1; j < C; j++)
countDP[i, j] = matrix[i, j] +
countDP[i - 1, j] +
countDP[i, j - 1] -
countDP[i - 1, j - 1];
// Loop to solve each query
for(int q = 0; q < Q; q++)
{
int i = q_i[q];
int j = q_j[q];
int min_dist = Math.Min(Math.Min(i, j),
Math.Min(R - i - 1,
C - j - 1));
int ans = -1, l = 0, u = min_dist;
// Binary Search to the side which
// have atmost in K 1's in square
while (l <= u)
{
int mid = (l + u) / 2;
int x1 = i - mid, x2 = i + mid;
int y1 = j - mid, y2 = j + mid;
// Count total number of 1s in
// the sub square considered
int count = countDP[x2, y2];
if (x1 > 0)
count -= countDP[x1 - 1, y2];
if (y1 > 0)
count -= countDP[x2, y1 - 1];
if (x1 > 0 && y1 > 0)
count += countDP[x1 - 1, y1 - 1];
// If the count is less than or
// equals to the maximum move
// to right half
if (count <= K)
{
ans = 2 * mid + 1;
l = mid + 1;
}
else
u = mid - 1;
}
Console.WriteLine(ans);
}
}
// Driver code
public static void Main()
{
int [,]matrix = { { 1, 0, 1, 0, 0 },
{ 1, 0, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 0, 0, 1, 0 } };
int K = 9, Q = 1;
int []q_i = { 1 };
int []q_j = { 2 };
largestSquare(matrix, 4, 5,
q_i, q_j, K, Q);
}
}
// This code is contributed by Stream_Cipher
Javascript
输出:
3
时间复杂度: O( R*C + Q*log(MIN_DIST) )
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。