Step1 Problem:
平面上有n个点(x, y), 你有一个宽W, 高H的框,问你一次最多可以框到几个点(包括框的边界)。
Step2 Ideas:
对于每个点(x, y),我们维护一个右上方的矩阵【(x, y) -> (x+w, y+h)】
对于每个点(x, y),你另外添加一个点(x+w, y)。从左到右扫描:遇到(x, y),区间[y, y+h]加1,遇到(x+w, y),区间[y, y+h]减1。
区间更新 用线段树维护。对于每次更新求 区间最大值即可。
Step3 Code:
#include<bits/stdc++.h>
using namespace std;
#define lson root<<1
#define rson root<<1|1
#define MID int mid = (l+r)/2
const int N = 1e4+100;
struct Node
{
int x, y, val;
bool operator < (const Node &b) const {
if(x == b.x) return val > b.val;
else return x < b.x;
}
};
struct node
{
int data, lazy;
};
int w, h;
Node b[N*2];
node a[N*4*4];
void updown(int root)
{
if(a[root].lazy)
{
a[lson].lazy += a[root].lazy;
a[rson].lazy += a[root].lazy;
a[lson].data += a[root].lazy;
a[rson].data += a[root].lazy;
a[root].lazy = 0;
}
}
void updata(int root, int l, int r, int pos)
{
if(b[pos].y <= l && r <= b[pos].y + h)
{
a[root].lazy += b[pos].val;
a[root].data += b[pos].val;
return ;
}
updown(root);
MID;
if(mid >= b[pos].y) updata(lson, l, mid, pos);
if(mid < b[pos].y + h) updata(rson, mid+1, r, pos);
a[root].data = max(a[lson].data, a[rson].data);
}
int main()
{
int n, x, y;
while(~scanf("%d", &n) && ~n)
{
scanf("%d %d", &w, &h);
for(int i = 1; i <= n; i++)
{
scanf("%d %d", &x, &y);
b[i*2-1] = (Node){x, y+2*N, 1};
b[i*2] = (Node){x+w, y+2*N, -1};
}
sort(b+1, b+2*n+1);
memset(a, 0, sizeof(a));
int ans = 0;
for(int i = 1; i <= 2*n; i++)
{
updata(1, 1, 4*N, i);
ans = max(ans, a[1].data);
}
printf("%d\n", ans);
}
}