题目大意
给出01矩阵求以(a, b) (c, d) 为左上和右下的矩形中的矩形(由0构成)的个数
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define INF 0x3f3f3f3f
#define rep0(i, n) for (int i = 0; i < n; i++)
#define rep1(i, n) for (int i = 1; i <= n; i++)
#define rep_0(i, n) for (int i = n - 1; i >= 0; i--)
#define rep_1(i, n) for (int i = n; i > 0; i--)
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define mem(x, y) memset(x, y, sizeof(x))
#define MAXN 50
using namespace std;
char g[MAXN][MAXN];
int n, m, dp[MAXN][MAXN][MAXN][MAXN];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE
int q;
mem(dp, 0);
scanf("%d %d %d", &n, &m, &q);
//输入图
rep0(i, n)
scanf("%s", g[i]);
rep0(i, n)
{
rep0(j, m)
{
if (g[i][j] == '1')
continue;
int pre = INF, flag1 = 0;
for (int a = i; a < n; a++)
{
int flag = 0;
for (int b = j; b < m; b++)
{
if (flag1)
{
dp[i][j][a][b] = dp[i][j][a - 1][b];
continue;
}
if (b > pre)
{
flag = 1;
dp[i][j][a][b] = dp[i][j][a][b - 1] + dp[i][j][a - 1][b] - dp[i][j][a - 1][b - 1];
continue;
}
if (flag)
{
dp[i][j][a][b] = dp[i][j][a][b - 1];
continue;
}
if (g[a][b] == '1')
{
if (a - 1 >= i && b - 1 >= j)
{
dp[i][j][a][b] = dp[i][j][a][b - 1] + dp[i][j][a - 1][b] - dp[i][j][a - 1][b - 1];
pre = b - 1;
}
else if (a - 1 >= i)
{
dp[i][j][a][b] = dp[i][j][a - 1][b];
flag1 = 1;
}
else
{
pre = b - 1;
dp[i][j][a][b] = dp[i][j][a][b - 1];
}
}
else
{
int &temp = dp[i][j][a][b];
if (a == i && b == j)
temp = 1;
else if (a == i)
temp = dp[i][j][a][b - 1] + 1;
else if (b == j)
temp = dp[i][j][a - 1][b] + 1;
else
temp = dp[i][j][a - 1][b] + dp[i][j][a][b - 1] - dp[i][j][a - 1][b - 1] + 1;
}
}
}
}
}
int a, b, c, d;
int re;
while (q--)
{
re = 0;
scanf("%d %d %d %d", &a, &b, &c, &d);
for (int i = a - 1; i <= c - 1; i++)
{
for (int j = b - 1; j <= d - 1; j++)
{
re += dp[i][j][c - 1][d - 1];
}
}
printf("%d\n", re);
}
return 0;
}