#P1682. 第3题-小美的完美矩形
-
2000ms
Tried: 392
Accepted: 148
Difficulty: 5
所属公司 :
美团
时间 :2024年3月9日
-
算法标签>前缀和
第3题-小美的完美矩形
思路:二维前缀和
n≤200,因此可以在O(n3)范围内求解
快速求一个矩形区域内的和:使用二维前缀和预处理
最终计算答案的时候,第一层循环枚举矩形长度len,第二,三层循环分别枚举矩形的左上角的端点(x,y)
对应右下角的端点则为(x+len−1,y+len−1)
具体可以参考代码
时间复杂度
O(n3)
C++
#include<bits/stdc++.h>
using namespace std;
const int N = 210;
int n;
char a[N][N];
int s[N][N];
int query(int x1,int y1,int x2,int y2){
return s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1];
}
int main()
{
cin >> n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
}
}
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ )
s[i][j] = s[i][j - 1] + s[i - 1][j] - s[i - 1][j - 1] + (a[i][j]=='1');
for(int len=1;len<=n;len++){
int cnt=0;
for(int x=1;x<=n-len+1;x++){
for(int y=1;y<=n-len+1;y++){
int sum=query(x,y,x+len-1,y+len-1);
if(sum*2==len*len){
cnt++;
}
}
}
cout<<cnt<<endl;
}
return 0;
}
Java
import java.util.Scanner;
public class Main {
static final int N = 210;
static int n;
static char[][] a = new char[N][N];
static int[][] s = new int[N][N];
static int query(int x1, int y1, int x2, int y2) {
return s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1];
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
n = scanner.nextInt();
for (int i = 1; i <= n; i++) {
String line = scanner.next();
for (int j = 1; j <= n; j++) {
a[i][j] = line.charAt(j - 1);
}
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
int value = a[i][j] == '1' ? 1 : 0;
s[i][j] = s[i][j - 1] + s[i - 1][j] - s[i - 1][j - 1] + value;
}
for (int len = 1; len <= n; len++) {
int cnt = 0;
for (int x = 1; x <= n - len + 1; x++) {
for (int y = 1; y <= n - len + 1; y++) {
int sum = query(x, y, x + len - 1, y + len - 1);
if (sum * 2 == len * len) {
cnt++;
}
}
}
System.out.println(cnt);
}
}
}
Python
n = int(input())
a = [input() for _ in range(n)]
s = [[0] * (n + 1) for _ in range(n + 1)]
def query(x1, y1, x2, y2):
return s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1]
for i in range(1, n + 1):
for j in range(1, n + 1):
s[i][j] = s[i][j - 1] + s[i - 1][j] - s[i - 1][j - 1] + (1 if a[i - 1][j - 1] == '1' else 0)
for length in range(1, n + 1):
cnt = 0
for x in range(1, n - length + 2):
for y in range(1, n - length + 2):
summation = query(x, y, x + length - 1, y + length - 1)
if summation * 2 == length ** 2:
cnt += 1
print(cnt)
题目描述
小美拿到了一个n×m的矩阵,其中每个元素是0或者1。
小美认为一个矩形区域是完美的,当且仅当该区域内0的数量恰好等于1的数量。现在,小美希望你回答有多少个i×i的完美矩形区域。你需要回答1≤i≤n的所有答案
输入描述
第一行输入一个正整数n,代表矩阵大小
接下来的n行,每行输入一个长度为n的01串,用来表示矩阵 1≤n≤200
输出描述
输出n行,第i行输出i×i的完美矩形区域的数量
样例
输入
4
1010
0101
1100
0011
输出
0
7
0
1