• 【二维前缀和】【CF】L Leverage MDT


    【二维前缀和】【CF】L Leverage MDT

    题目传送门

    image

    题意:

    • 条件
      • 可以实现单行的01变换;
      • 行与行之间的变换是独立的;
    • 问题
      • 求最长的0方阵或者1方阵的长度平方

    参考后的思路整理:

    若在某个位置i,j和位置i,j+1两个位置上的字符必然不同,那么不妨定义i,j位置上具有一个疙瘩。

    且如果一个方阵没有疙瘩,则说明这个方阵的元素可以全部相同。

    这里还是不太严谨,比如以i,j为右下角的方阵是否为单纯的方阵实际上和第j列是否具有疙瘩没有关系(因为这一列的疙瘩代表的是第j列和第j+1列的不同的关系,而第j+1列与当前要探索的方阵没有关系)。

    二维前缀和+二分可能长度

    二维数组用于存储当前i,j位置具有的疙瘩数

    #include <bits/stdc++.h>
    using namespace std;
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0' && ch<='9')
            x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    const int N = 1e3+100;
    int n,m,dp[N][N];
    bool check(int x,int y,int len)
    {
    	return (dp[x][y-1]-dp[x][y-len]-dp[x-len][y-1]+dp[x-len][y-len])==0;
    }
    int main()
    {
    	n = read(), m = read();
    	char g[n+1][m+1];
    	for(int i = 1; i<=n;i++)
            cin>>g[i]+1;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m-1;j++)
                if(g[i][j+1]!=g[i][j]) dp[i][j]=1;
        
        for(int i=1;i<=n;i++)
           for(int j=1;j<=m;j++)
               dp[i][j] += dp[i][j-1]+dp[i-1][j]-dp[i-1][j-1];
        
        int ans=0;
        for(int i =1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
            	int l=1,r=min(i,j),save;
            	while(l<=r)
            	{
            		int mid = l+r>>1;
            		if(check(i,j,mid))
            			save=mid,l=mid+1;
    				else 
    				    r=mid-1;
    			}
    			ans=max(ans,save);
    		}
    	cout<<ans*ans;
        return 0;
    }
    
    
  • 相关阅读:
    获取用户电脑的上网IP地址
    array_multisort() 排序说明
    phpcms2008 sp4 升级到v9
    js验证
    鼠标滑过出现气泡提示框
    鼠标滑过右侧显示菜单
    tab切换
    分享到新浪,人人,开心,天涯,豆瓣,搜狐,腾讯等的代码
    判断checkbox是否被选中,判定选中的个数!
    <object >属性
  • 原文地址:https://www.cnblogs.com/BeautifulWater/p/15455865.html
Copyright © 2020-2023  润新知