地址:http://poj.org/problem?id=2029
题意:
给一个w*h的矩阵,n个坐标点被标记,给出s*t的矩阵,问它能容纳最多多少个标记点。
解析:
暴力枚举每一块区间,注意坐标点,比如定位i,j,左上角点应该为:i-s+1,j-t+1。算的时候还是那一套,画图更容易理解。
接下来就是二维树状数组的维护了。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn=150; int c[maxn][maxn]; int lowbit(int x) { return x&(-x); } void update(int x,int y) { for(int i=x;i<maxn;i+=lowbit(i)) for(int j=y;j<maxn;j+=lowbit(j)) c[i][j]++; } int getsum(int x,int y) { int sum=0; for(int i=x;i>=1;i-=lowbit(i)) { for(int j=y;j>=1;j-=lowbit(j)) sum+=c[i][j]; } return sum; } int getall(int x1,int y1,int x2,int y2) { return getsum(x2,y2)-getsum(x1-1,y2)-getsum(x2,y1-1)+getsum(x1-1,y1-1); } int main() { int n; while(scanf("%d",&n)&&n) { memset(c,0,sizeof(c)); int w,h; scanf("%d%d",&w,&h); while(n--) { int i,j; cin>>i>>j; update(i,j); } int s,t; scanf("%d%d",&s,&t); int maxx=0; for(int i=s;i<=w;i++) { for(int j=t;j<=h;j++) { maxx=max(maxx,getall(i-s+1,j-t+1,i,j)); } } cout<<maxx<<endl; } }