找出涂有 K 个黑色的网格中 p 边正方形的数量
给定一个大小为 H*W 的网格,所有单元格最初都是白色的。给定数组中的 N 对 (i, j),对于每一对,将单元格 (i, j) 涂上黑色。任务是确定在绘制 N 个单元格后,网格中有多少个大小为 p×p 的正方形包含恰好 K 个黑色单元格。
例子:
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
方法:
- 首先要观察的是,如果起点不同,一个 p*p 子网格将与另一个不同。
- 第二件事是,如果单元格被涂成黑色,它将有助于 p^2 个不同的 p*p 子网格。
- 例如,假设单元格 [i, j] 被涂成黑色。然后它将为所有具有起点的子网格贡献额外的 +1
[i-p+1][j-p+1] 到 [i, j]。 - 由于最多可以有 N 个黑色,对于每个黑色单元格进行 p*p 迭代并更新其对每个 p*p 子网格的贡献。
- 保留地图以跟踪网格中每个单元格的答案。
下面是上述方法的实现:
C++
// C++ implementation of the above approach
#include
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 > painted)
{
// Map to keep track for each cell that is
// being affected by other blacks
map, 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 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 > 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;
}
Java
// Java implementation of the above approach
import java.util.*;
import java.awt.Point;
class GFG
{
// Function to check if a cell is safe or not
static boolean isSafe(int x, int y, int h,
int w, int p)
{
if (x >= 1 && x <= h)
{
if (y >= 1 && 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
static void CountSquares(int h, int w, int n, int K,
int p, List painted)
{
// Map to keep track for each cell that is
// being affected by other blacks
HashMap mp = new HashMap<>();
for(int i = 0; i < painted.size(); ++i)
{
int x = painted.get(i).x;
int y = painted.get(i).y;
// 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))
{
Point temp = new Point(j, k);
// No need to increase the value
// as there is no sense of paint
// 2 blacks in one cell
if (mp.containsKey(temp))
{
if (mp.get(temp) >= p * p)
continue;
else
mp.put(temp, mp.get(temp) + 1);
}
else
{
mp.put(temp, 1);
}
}
}
}
}
// Answer array to store the answer.
int[] ans = new int[p * p + 1];
for (Map.Entry x : mp.entrySet())
{
int cnt = x.getValue();
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;
System.out.println(ans[K]);
return;
}
// Driver code
public static void main(String[] args)
{
int H = 4, W = 5, N = 8, K = 4, P = 3;
List painted = new ArrayList();
// Initializing matrix
painted.add(new Point(3, 1));
painted.add(new Point(3, 2));
painted.add(new Point(3, 4));
painted.add(new Point(4, 4));
painted.add(new Point(1, 5));
painted.add(new Point(2, 3));
painted.add(new Point(1, 1));
painted.add(new Point(1, 4));
CountSquares(H, W, N, K, P, painted);
}
}
// This code is contributed by divyesh072019
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
C#
// C# implementation of the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to check if a cell is safe or not
static bool isSafe(int x, int y, int h,
int w, int p)
{
if (x >= 1 && x <= h)
{
if (y >= 1 && 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
static void CountSquares(int h, int w, int n, int K,
int p, List> painted)
{
// Map to keep track for each cell that is
// being affected by other blacks
Dictionary, int> mp = new Dictionary, int>();
for(int i = 0; i < painted.Count; ++i)
{
int x = painted[i].Item1;
int y = painted[i].Item2;
// 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))
{
Tuple temp = new Tuple(j, k);
// No need to increase the value
// as there is no sense of paint
// 2 blacks in one cell
if (mp.ContainsKey(temp))
{
if (mp[temp] >= p * p)
continue;
else
mp[temp]++;
}
else
{
mp[temp] = 1;
}
}
}
}
}
// Answer array to store the answer.
int[] ans = new int[p * p + 1];
foreach(KeyValuePair, int> x in mp)
{
int cnt = x.Value;
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;
Console.WriteLine(ans[K]);
return;
}
// Driver Code
static void Main()
{
int H = 4, W = 5, N = 8, K = 4, P = 3;
List> painted = new List>();
// Initializing matrix
painted.Add(new Tuple(3, 1));
painted.Add(new Tuple(3, 2));
painted.Add(new Tuple(3, 4));
painted.Add(new Tuple(4, 4));
painted.Add(new Tuple(1, 5));
painted.Add(new Tuple(2, 3));
painted.Add(new Tuple(1, 1));
painted.Add(new Tuple(1, 4));
CountSquares(H, W, N, K, P, painted);
}
}
// This code is contributed by divyeshrabadiya07
Javascript
输出:
4
时间复杂度: O(N*p*p)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。