POJ 2029 Get Many PersimmonTrees(二维树状数组or递推)

来源:互联网 发布:怎样做app软件 编辑:程序博客网 时间:2024/06/05 03:46

POJ 2029 Get Many PersimmonTrees(二维树状数组or递推)

分析:这道题看起来能用很多方法做:递推,二维树状数组。

解法一:二维树状数组

先用二维树状数组来做:即一颗一颗的把树插入到树状数组中,然后遍历所有可行的格子(x,y)求出由(x-S+1,y-T+1)为左上角,(x,y)为右下角构成的矩形内有多少个树即可,该值为:

Sum(x,y)+sum(x-S,y-T)-sum(x,y-T)-sum(x-S,y)。

AC代码:16ms

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXN=105;int c[MAXN][MAXN];int W,H;int S,T;int lowbit(int x){    return x&(-x);}int sum(int i,int j){    int res=0;    for(int x=i; x>0; x-=lowbit(x))        for(int y=j; y>0; y-=lowbit(y))            res +=c[x][y];    return res;}void add(int i,int j)//д╛хо╪с1{    for(int x=i; x<=W; x+=lowbit(x))        for(int y=j; y<=H; y+=lowbit(y))            c[x][y] +=1;}int main(){    int N;    while(scanf("%d",&N)==1&&N)    {        memset(c,0,sizeof(c));        scanf("%d%d",&W,&H);        while(N--)        {            int x,y;            scanf("%d%d",&x,&y);            add(x,y);        }        scanf("%d%d",&S,&T);        int max_num=0;        for(int x=1; x+S-1<=W; x++)            for(int y=1; y+T-1<=H; y++)            {                int temp = sum(x+S-1,y+T-1)+sum(x-1,y-1)-sum(x-1,y+T-1)-sum(x+S-1,y-1);                max_num=max(max_num,temp);            }        printf("%d\n",max_num);    }    return 0;}


解法二:递推

要递推计算就要先计算所有的二维前缀和。令S[x][y]为以格子(1,1)为左上角,(x,y)为右下角的矩形中包含的树总数。

S[x][y] = S[x-1][y]+ S[x][y-1]- S[x-1][y-1]+A[x][y];其中A[x][y]=1表示(x,y)是树,否则不是树。

然后以(x,y)为左上角且以(x+W-1,y+H-1)为右下角的矩形中含有的树总数为:S[x+W-1][y+H-1]+S[x-1][y-1]-S[x-1][y+H-1]-S[x+W-1][y-1].

AC代码:0ms,递推更快点

//递推解法#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXN=105;int a[MAXN][MAXN];int s[MAXN][MAXN];int W,H,S,T;int N;int main(){    while(scanf("%d",&N)==1&&N)    {        memset(a,0,sizeof(a));        memset(s,0,sizeof(s));        scanf("%d%d",&W,&H);        while(N--)        {            int x,y;            scanf("%d%d",&x,&y);            a[x][y]=1;        }        scanf("%d%d",&S,&T);        for(int x=1;x<=W;x++)            for(int y=1;y<=H;y++)            {                s[x][y]=s[x-1][y]+ s[x][y-1]- s[x-1][y-1]+a[x][y];            }        int max_num=0;        for(int x=1;x+S-1<=W;x++)            for(int y=1;y+T-1<=H;y++)            {                int temp = s[x+S-1][y+T-1]+s[x-1][y-1]-s[x-1][y+T-1]-s[x+S-1][y-1];                max_num=max(max_num,temp);            }        printf("%d\n",max_num);    }}


0 0