[NowCoder] 牛牛数星星
一闪一闪亮晶晶,满天都是小星星,牛牛晚上闲来无聊,便躺在床上数星星。
牛牛把星星图看成一个平面,左上角为原点(坐标为(1, 1))。现在有n颗星星,他给每颗星星都标上坐标(xi,yi),表示这颗星星在第x行,第y列。
现在,牛牛想问你m个问题,给你两个点的坐标(a1, b1)(a2,b2),表示一个矩形的左上角的点坐标和右下角的点坐标,请问在这个矩形内有多少颗星星(边界上的点也算是矩形内)。
输入描述:
第一行输入一个数字n(1≤n≤100000),表示星星的颗数。
接下来的n行,每行输入两个数x和y(1≤xy≤1000),表示星星的位置。
然后输入一个数字m(1≤m≤100000), 表示牛牛询问问题的个数。
接下来m行,每行输入四个数字a1,b1,a2,b2(1≤a1<a2≤1000), (1≤b1<b2≤1000)
题目保证两颗星星不会存在于同一个位置。
输出描述:
输出一共包含m行,每行表示与之对应的每个问题的答案。
示例1
输入
4 1 1 2 2 3 3 1 3 4 1 1 2 2 1 1 3 3 2 2 3 3 1 2 2 3
输出
2 4 2 2
蛮力法超过了时间限制
只有使用二维前缀来进行矩阵和降维,在O(1)的时间内计算出星星的个数。
#include <iostream> #include <vector> using namespace std; int main() { int n; cin >> n; vector<vector<int>> tbl(1001, vector<int>(1001, 0)); vector<vector<int>> sum(tbl); int x, y; for (int i = 0; i < n; ++i) { cin >> x >> y; tbl[x][y] = 1; } for (int i = 1; i < 1001; ++i) { for (int j = 1; j < 1001; ++j) { sum[i][j] = tbl[i][j] + sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1]; } } int m; cin >> m; int ax, ay, bx, by; for (int i = 0; i < m; ++i) { cin >> ax >> ay >> bx >> by; int count = sum[bx][by] + sum[ax-1][ay-1] - sum[bx][ay-1] - sum[ax-1][by]; cout << count << endl; } return 0; }