每日一题 — 2020 - 04 - 19

题目链接

可以看出是差分和前缀和(差分的话自己并不熟练),这题主要是对前面知识进行回顾了差分和前缀和的知识。


解题思路:

  • 首先这个先利用差分来记录每个点的值,这里利用差分,然后类似于前缀和的形式来求出每个位置的值
  • 然后我们利用前缀和(二维前缀和)
  • 然后最终求出即可

这里需要注意的是:(注意形式)

二维前缀和:

a[i][j] = a[i][j] + a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1];

求出结果:

a[x2][y2] - a[x1 - 1][y2] - a[x2][y1 - 1] + a[x1 - 1][y1 - 1];


代码:

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

long long a[2010][2010];

int main(){
	int n, m, k, q;
	scanf("%d%d%d%d",&n,&m,&k,&q);
	for (int i = 0; i < k; i ++){
		int x1, y1, x2, y2;
		scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
		a[x1][y1] += 1;
		a[x2 + 1][y1] -= 1;
		a[x1][y2 + 1] -= 1;
		a[x2 + 1][y2 + 1] += 1;
	}
	
	// 差分完每一块的值
	for (int i = 1; i <= n; i++){
		for (int j = 1; j <= m; j ++){
			a[i][j] = a[i][j] + a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1];
		}
	}

	// 前缀和
	for (int i = 1; i <= n; i++){
		for (int j = 1; j <= m; j ++){
			a[i][j] = a[i][j] + a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1];
		}
	}

	for (int i  = 0 ; i < q; i ++){
		int x1, y1, x2, y2;
		scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
		printf("%lld\n",a[x2][y2] - a[x1 - 1][y2] - a[x2][y1 - 1] + a[x1 - 1][y1 - 1]);
	}
	return 0;

}
发布了121 篇原创文章 · 获赞 7 · 访问量 4316

猜你喜欢

转载自blog.csdn.net/LiangNiuMu/article/details/105626505
今日推荐