Find the number of p-sided squares in a grid with K blacks painted
Given a grid of size H*W with all cells initially white. Given N pairs (i, j) in an array, for each pair, paint cell (i, j) with black colour. The task is to determine how many squares of size p×p of the grid contains exactly K black cells, after N cells being painted.
Examples:
Input: H = 4, W = 5, N = 8, K = 4, p = 3 arr=[ (3, 1), (3, 2), (3, 4), (4, 4), (1, 5), (2, 3), (1, 1), (1, 4) ] Output: 4 Cells the are being painted are shown in the figure below: Here p = 3. There are six subrectangles of size 3*3. Two of them contain three black cells each, and the remaining four contain four black cells each.Input: H = 1, W = 1, N = 1, K = 1, p = 1 arr=[ (1, 1) ] Output: 1
Approach:
- First thing to observe is that one p*p sub-grid will be different from the other if their starting points are different.
- Second thing is that if the cell is painted black, it will contribute to p^2 different p*p sub-grids.
- For example, suppose cell [i, j] is painted black. Then it will contribute additional +1 to all the subgrids having starting point
[i-p+1][j-p+1] to [i, j]. - Since there can be at most N blacks, for each black cell do p*p iterations and update its contribution for each p*p sub-grids.
- Keep a map to keep track of answer for each cell of the grid.
Below is the implementation of the above approach:
C++
// C++ implementation of the above approach #include <bits/stdc++.h> using namespace std; // Function to check if a cell is safe or not bool isSafe( int x, int y, int h, int w, int p) { if (x >= 1 and x <= h) { if (y >= 1 and y <= w) { if (x + p - 1 <= h) { if (y + p - 1 <= w) { return true ; } } } } return false ; } // Function to print the number of p-sided squares // having k blacks void CountSquares( int h, int w, int n, int k, int p, vector<pair< int , int > > painted) { // Map to keep track for each cell that is // being affected by other blacks map<pair< int , int >, int > mp; for ( int i = 0; i < painted.size(); ++i) { int x = painted[i].first; int y = painted[i].second; // For a particular row x and column y, // it will affect all the cells starting // from row = x-p+1 and column = y-p+1 // and ending at x, y // hence there will be total // of p^2 different cells for ( int j = x - p + 1; j <= x; ++j) { for ( int k = y - p + 1; k <= y; ++k) { // If the cell is safe if (isSafe(j, k, h, w, p)) { pair< int , int > temp = { j, k }; // No need to increase the value // as there is no sense of paint // 2 blacks in one cell if (mp[temp] >= p * p) continue ; else mp[temp]++; } } } } // Answer array to store the answer. int ans[p * p + 1]; memset (ans, 0, sizeof ans); for ( auto & x : mp) { int cnt = x.second; ans[cnt]++; } // sum variable to store sum for all the p*p sub // grids painted with 1 black, 2 black, // 3 black, ..., p^2 blacks, // Since there is no meaning in painting p*p sub // grid with p^2+1 or more blacks int sum = 0; for ( int i = 1; i <= p * p; ++i) sum = sum + ans[i]; // There will be total of // (h-p+1) * (w-p+1), p*p sub grids int total = (h - p + 1) * (w - p + 1); ans[0] = total - sum; cout << ans[k] << endl; return ; } // Driver code int main() { int H = 4, W = 5, N = 8, K = 4, P = 3; vector<pair< int , int > > painted; // Initializing matrix painted.push_back({ 3, 1 }); painted.push_back({ 3, 2 }); painted.push_back({ 3, 4 }); painted.push_back({ 4, 4 }); painted.push_back({ 1, 5 }); painted.push_back({ 2, 3 }); painted.push_back({ 1, 1 }); painted.push_back({ 1, 4 }); CountSquares(H, W, N, K, P, painted); return 0; } |
chevron_right
filter_none
Python3
# Python3 implementation of the above approach # Function to check if a cell is safe or not def isSafe(x, y, h, w, p): if (x > = 1 and x < = h): if (y > = 1 and y < = w): if (x + p - 1 < = h): if (y + p - 1 < = w): return True return False # Function to print the number of p-sided squares # having k blacks def CountSquares(h, w, n, k, p, painted): # Map to keep track for each cell that is # being affected by other blacks mp = dict () for i in range ( len (painted)): x = painted[i][ 0 ] y = painted[i][ 1 ] # For a particular row x and column y, # it will affect all the cells starting # from row = x-p+1 and column = y-p+1 # and ending at x, y # hence there will be total # of p^2 different cells for j in range (x - p + 1 , x + 1 ): for k in range (y - p + 1 , y + 1 ): # If the cell is safe if (isSafe(j, k, h, w, p)): temp = (j, k) # No need to increase the value # as there is no sense of pa # 2 blacks in one cell if (temp in mp.keys() and mp[temp] > = p * p): continue else : mp[temp] = mp.get(temp, 0 ) + 1 # Answer array to store the answer. ans = [ 0 for i in range (p * p + 1 )] # memset(ans, 0, sizeof ans) for x in mp: cnt = mp[x] ans[cnt] + = 1 # Sum variable to store Sum for all the p*p sub # grids painted with 1 black, 2 black, # 3 black, ..., p^2 blacks, # Since there is no meaning in painting p*p sub # grid with p^2+1 or more blacks Sum = 0 for i in range ( 1 , p * p + 1 ): Sum = Sum + ans[i] # There will be total of # (h-p+1) * (w-p+1), p*p sub grids total = (h - p + 1 ) * (w - p + 1 ) ans[ 0 ] = total - Sum print (ans[k]) return # Driver code H = 4 W = 5 N = 8 K = 4 P = 3 painted = [] # Initializing matrix painted.append([ 3 , 1 ]) painted.append([ 3 , 2 ]) painted.append([ 3 , 4 ]) painted.append([ 4 , 4 ]) painted.append([ 1 , 5 ]) painted.append([ 2 , 3 ]) painted.append([ 1 , 1 ]) painted.append([ 1 , 4 ]) CountSquares(H, W, N, K, P, painted) # This code is contributed by Mohit Kumar |
chevron_right
filter_none
Output:
4
Time Complexity : O(N*p*p)
Recommended Posts:
- Sum of the count of number of adjacent squares in an M X N grid
- Count Magic squares in a grid
- Find an N x N grid whose xor of every row and column is equal
- Given an n x n square matrix, find sum of all sub-squares of size k x k
- Find a point that lies inside exactly K given squares
- Possible number of Rectangle and Squares with the given set of elements
- Count number of squares in a rectangle
- Count the total number of squares that can be visited by Bishop in one move
- Number of shortest paths to reach every cell from bottom-left cell in the grid
- Find a number which give minimum sum when XOR with every number of array of integers
- Search a Word in a 2D Grid of characters
- Maximum sum in a 2 x n grid such that no two elements are adjacent
- Minimum distance to the end of a grid from source
- Count possible moves in the given direction in a grid
- Unique paths in a Grid with Obstacles
If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.