[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;
}

 



posted @ 2018-06-26 16:28  immjc  阅读(590)  评论(0编辑  收藏  举报