zoukankan      html  css  js  c++  java
  • Codeforces Round #619 (Div. 2)E思维+二维RMQ

    题:https://codeforces.com/contest/1301/problem/E

    题意:给个n*m的图形,q个询问,每次询问问询问区间最大的合法logo的面积是多少

    分析:由于logo是由4个同色的小正方形组成的,所以我们先考虑一个数组val[i][j]表示[i][j]位置为‘R' , [i+1][j]位置为’Y‘,[i][j+1]位置为’G‘,[i+1][j+1]位置为’B'所能形成的最大图案边长是多少;

       因为这样就只要预处理‘R’正方形沿着左上能形成的最大正方形,“Y”沿着左下能形成的最大正方形,’G‘沿着右上能形成的最大正方形,”B“沿着右下能形成的最大正方形,然后对于位置[i][j]就取min这四者;

       对于询问,我们只要二分答案搜到最大符合条件的就行了,注意这里的二分的mid,假设询问[r1,c1,r2,c2],则搜索访问应该在[r1+mid-1,c1+mid-1,r2-mid,c2-mid]的范围内搜索才是合法的;

       因为我们在二分时要求满足条件的mid就行,所以这里对val进行倍增处理;

       合法性:因为小的合法图案一定在大的合法图案里面,所以对val取的图案也许是超过询问范围,但我们上面已经对询问范围进行如上缩减,所以是合法的

    #include<bits/stdc++.h>
    using namespace std;
    const int M=505;
    const int N=10;
    int ex[4][M][M];
    int n,m,q;
    int val[M][M],f[N][N][M][M],lg[M];
    char s[M][M];
    void RMQ(int n,int m){
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                f[0][0][i+1][j+1]=val[i][j];
        for(int i=2;i<M;i++)
            lg[i]=1+lg[i/2];
        for(int i=1;i<=n;i++)
            for(int k2=1;(1<<k2)<=m;k2++)
                for(int j=1;j<=m-(1<<k2)+1;j++)
                    f[0][k2][i][j]=max(f[0][k2-1][i][j],f[0][k2-1][i][j+(1<<(k2-1))]);
        for(int k1=1;(1<<k1)<=n;k1++)
            for(int i=1;i<=n-(1<<k1)+1;i++)
                for(int k2=0;(1<<k2)<=m;k2++)
                    for(int j=1;j<=m-(1<<k2)+1;j++)
                        f[k1][k2][i][j]=max(f[k1-1][k2][i][j],f[k1-1][k2][i+(1<<(k1-1))][j]);
    }
    
    
    int query(int x1,int y1,int x2,int y2){
        int k1=lg[x2-x1+1];
        int k2=lg[y2-y1+1];
        x2=x2-(1<<k1)+1;
        y2=y2-(1<<k2)+1;
        return max(f[k1][k2][x1][y1],max(f[k1][k2][x1][y2],max(f[k1][k2][x2][y1],f[k1][k2][x2][y2])));
    }
    bool check(int r1,int c1,int r2,int c2,int midd){
        r1=r1+midd-1;
        c1=c1+midd-1;
        r2=r2-midd;
        c2=c2-midd;
        if(r1>r2||c1>c2)
            return false;
        return query(r1,c1,r2,c2)>=midd;
    }
    void color(int fx,int fy,char c,int k){///根据进来的参数不同,组成不同方向相同颜色的最大正方形 
        int stx=0,sty=0;
        if(fx==-1)stx=n-1;
        if(fy==-1)sty=m-1;
        ///while遍历二维数组 
        while(stx<n&&stx>=0){
            while(sty<m&&sty>=0){
                if(s[stx][sty]==c){
                    ex[k][stx][sty]=1;
                    if(stx-fx>=0&&stx-fx<n&&sty-fy>=0&&sty-fy<m){///正方形区域取最小值 
                        if(s[stx-fx][sty]==c&&s[stx][sty-fy]==c&&s[stx-fx][sty-fy]==c){
                            ex[k][stx][sty]=min(ex[k][stx-fx][sty],
                                             min(ex[k][stx][sty-fy],ex[k][stx-fx][sty-fy]))+1;
                        }
                    }
                }
                sty+=fy;
            }
            sty=0;if(fy==-1)sty=m-1;
            stx+=fx;
        }
    }
    int main(){
        scanf("%d%d%d",&n,&m,&q);
        for(int i=0;i<n;i++)
            scanf("%s",s[i]); 
        //1
        color(1,1,'R',0);
        color(-1,1,'Y',1);
        color(1,-1,'G',2);
        color(-1,-1,'B',3);
        for(int i=0;i<n-1;i++){
            for(int j=0;j<m-1;j++){
                if(s[i][j]=='R'&&s[i+1][j]=='Y'&&s[i][j+1]=='G'&&s[i+1][j+1]=='B'){
                    val[i][j]=min(ex[0][i][j],min(ex[1][i+1][j],min(ex[2][i][j+1],ex[3][i+1][j+1])));
                }
            }
        }
        //2
        RMQ(n,m);
    
        //3
        for(int i=0;i<q;i++){
            int r1,c1,r2,c2,ans=0;
            scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
            int l=0,r=min(r2-r1,c2-c1);
            while(l<=r){
                int midd=(l+r)>>1;
                if(check(r1,c1,r2,c2,midd)){
                    ans=midd;
                    l=midd+1;
                }
                else
                    r=midd-1;
            }
            printf("%d
    ",4*ans*ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Mvc+三层(批量添加、删除、修改)
    js中判断复选款是否选中
    EF的优缺点
    Git tricks: Unstaging files
    Using Git Submodules
    English Learning
    wix xslt for adding node
    The breakpoint will not currently be hit. No symbols have been loaded for this document."
    Use XSLT in wix
    mfc110ud.dll not found
  • 原文地址:https://www.cnblogs.com/starve/p/12348177.html
Copyright © 2011-2022 走看看