给你一个h行w列的矩阵,‘.’表示空位,‘#’表示非空位,每次询问给出一个矩形左上顶点和右下顶点,问有多少种方案将一张1*21∗2的“骨牌”摆进这个子矩阵中(每个骨牌会覆盖相邻的两个空位)
输入样例#1:
5 8
…#…#
.#…
##.#…
##…#.##

4
1 1 2 3
4 1 4 1
1 2 4 5
2 5 5 8
输出样例#1:
4
0
10
15
思路:二位前缀和

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1005;
int a[maxn][maxn];
int L[maxn][maxn], H[maxn][maxn], sum[maxn][maxn];
char str[maxn];
int main() {
	int n, m, q;
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++) {
		scanf("%s", str + 1);
		for (int j = 1; j <= m; j++) {
			if (str[j] == '.') a[i][j] = 1;
			L[i][j] = L[i][j - 1];
			H[i][j] = H[i - 1][j];
			if (a[i][j] && a[i - 1][j]) L[i][j]++;
			if (a[i][j] && a[i][j - 1]) H[i][j]++;
			sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + (a[i][j] && a[i - 1][j]) + (a[i][j] && a[i][j - 1]);
		}
	}
	scanf("%d", &q);
	int x1, y1, x2, y2;
	while (q--) {
		scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
		printf("%d\n", sum[x2][y2] - sum[x1 - 1][y2] - sum[x2][y1 - 1] + sum[x1 - 1][y1 - 1] - L[x1][y2] + L[x1][y1 - 1] - H[x2][y1] + H[x1 - 1][y1]);
	}
	return 0;
}