社团游戏-题解

社团游戏

https://ac.nowcoder.com/acm/contest/6874/H

题目描述
在民风淳朴的雏见泽,号称能“完美犯罪”的天才牛牛,又开始和社团的萌妹子牛妹玩起了游戏。

在今天的游戏中,牛牛将会得到一个n\times mn×m且全为小写字母的矩阵,他可以从矩阵中任选一块正方形,但必须保证该正方形中任意一类小写字母个数之和不能超过kk,换而言之,在该正方形中,‘a’字符个数不能超过kk,‘b’字符个数不能超过kk,…,‘z’字符个数不能超过kk。

现在牛牛想知道,以(i,j)(i,j)为左上角且符合以上要求的正方形中,边长最大的是多少?
思路:枚举横的,枚举竖的,暴力就行。
代码:

//社团游戏
#include <bits/stdc++.h>
using namespace std;
int sum[27][505][505];
char s[505][505];
int n,m,k;
int ans[505][505];
bool jud(int x,int y,int p,int q){
    for(int l=0;l<26;++l){
        if(sum[l][p][q]-sum[l][p][y-1]-sum[l][x-1][q]+sum[l][x-1][y-1]>k) return false;
    }
    return true;
}
int main(){
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;++i) scanf("%s",s[i]+1);
    for(int l=0;l<26;++l){
        for(int i=1;i<=n;++i){
            for(int j=1;j<=m;++j){
                sum[l][i][j]=-sum[l][i-1][j-1]+sum[l][i][j-1]+sum[l][i-1][j]+(s[i][j]-'a'==l);
            }
        }
    }
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            int l=1,r=min(n-i+1,m-j+1);
            while(l<=r){
                int mid=(l+r)>>1;
                if(jud(i,j,i+mid-1,j+mid-1)){
                    l=mid+1;
                } else{
                    r=mid-1;
                }
            }
            ans[i][j]=r;
        }
    }
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
             printf("%d ",ans[i][j]);   
        }
        printf("\n");
    }


}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务