P1369 矩形 [二维前缀和]

https://www.luogu.com.cn/problem/P1369
前缀和
黄色题
思路:
二维前缀和模板(但要注意减掉矩阵的中心点数)
#include<bits/stdc++.h>            //蒟蒻常用的万能头文件 QAQ
using namespace std;
int n,G[1005][1005],maxx=-1,maxy=-1,x,y,maxn=0;
int fff(int i,int j,int ii,int jj){        //fff函数返回矩形左上角为(i,j)、右下角为(ii,jj)矩形内部(包括边上)的点数 
    if(i>=ii||j>=jj)                    //在挖空矩形时可能矩形没有“心”,要判断一下,要返回0,因为此时挖不到东西 
        return 0;
    int sum;                            
    sum=G[ii][jj]-G[i-1][jj]-G[ii][j-1]+G[i-1][j-1];    //sum用于计算当前矩形中的点数,具体如何实现看上面解析哦QAQ 
    return sum;                                            //返回矩形上的点数 
}

int main(){                    //这里是主函数qwq 
    scanf("%d",&n);
    for(int i=1;i<=n;i++){           //这里读入各个点的坐标,将其赋为1 
        scanf("%d%d",&x,&y);         //因为各点的横、纵坐标在1~100范围内,所以不会为负数 
        if(x>maxx)                   //但是如果每次都是100*100的找效率很慢 
            maxx=x;                     //所以用maxx、maxy表示此矩形做多能达到的地方 
        if(y>maxy)
            maxy=y;
        G[x][y]=1;
    }
    for(int i=1;i<=maxx;i++)         //核心1:建立前缀和矩形的图像 
        for(int j=1;j<=maxy;j++)     //此处用递推写的 qwq 
            G[i][j]=G[i-1][j]+G[i][j-1]-G[i-1][j-1]+G[i][j];        //表示(i,j)点上方、左方和左上方的点数 
    for(int i=1;i<=maxx;i++)
        for(int j=1;j<=maxy;j++)
            for(int ii=2;ii<=maxx;ii++)                //矩形左上角坐标为(i,j),右下角坐标为(ii,jj) 
                for(int jj=2;jj<=maxy;jj++){        //暴力枚举一下所有可能生成的矩形 
                    if(i>=ii||j>=jj)                //如果这个矩形不合法则continue 
                        continue;
                    int ans=fff(i,j,ii,jj);            //这里可以看一下上面fff函数的解析 
                    ans-=fff(i+1,j+1,ii-1,jj-1);    //把矩形实心部分挖掉,ans变成四条边上的点数 
                    maxn=max(maxn,ans);                //比较一下在矩形边上可以得到的最大点数 
            }
    printf("%d",maxn);                    //输出可以得到的最多的点数 
    return 0;                            //完美结束QWQ 
} 

 

posted @ 2022-08-10 15:21  -イレイナ  阅读(78)  评论(0)    收藏  举报