zoukankan      html  css  js  c++  java
  • P1387 最大正方形

    先是传送门:https://www.luogu.com.cn/problem/P1387

    这题其实不一定要悬线法(主要是我一看到题目就想到了)

    这题实质是要求图里最大正方形(没错,就是我之前的模板)

    首先是暴力打法:求二维前缀和,再一波操作

    二维前缀和:f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1]+a[i][j];

    #include <bits/stdc++.h>
    using namespace std;
    int a[105][105];
    int f[105][105];
    int main()
    {
        int n,m,s,ans=0;
        cin>>n>>m; s=min(n,m);
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        cin>>a[i][j],f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1]+a[i][j];
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        for(int k=ans;k<=s;k++)
        {
            int x=i+k-1; int y=j+k-1;
            if(x>n || y>m || f[i-1][j-1]-f[x][j-1]-f[i-1][y]+f[x][y]!=k*k) break;
            if(ans<k) ans=k;
        }
        cout<<ans;
        return 0;
    }

    同样,你也可以用普通的DP

    公式也很好推:if (a[i][j]==1) f[i][j]=min(min(f[i][j-1],f[i-1][j]),f[i-1][j-1])+1;

    #include <iostream>
    #include <cstdio>
    using namespace std;
    int a[101][101],n,m,f[101][101],ans;
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;++i)
            for (int j=1;j<=m;++j)
            {
                scanf("%d",&a[i][j]);
                if (a[i][j]==1) f[i][j]=min(min(f[i][j-1],f[i-1][j]),f[i-1][j-1])+1;
                ans=max(ans,f[i][j]);
            }
        printf("%d",ans);
    }

    最后就是悬线法了

    #include <bits/stdc++.h>
    using namespace std;
    int a[105][105],l[105][105],r[105][105],up[105][105];
    int main()
    {
        int n,m,ans=0;
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            cin>>a[i][j];
            l[i][j]=r[i][j]=j;
            up[i][j]=1;
        }
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        if(a[i][j] && a[i][j-1]) l[i][j]=l[i][j-1];
        for(int i=1;i<=n;i++)
        for(int j=m;j>=1;j--)
        if(a[i][j] && a[i][j+1]) r[i][j]=r[i][j+1];
        for(int i=2;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(a[i][j]==a[i-1][j]==1)
            {
                l[i][j]=max(l[i][j],l[i-1][j]);
                r[i][j]=min(r[i-1][j],r[i][j]);
                up[i][j]=up[i-1][j]+1;
            }
            int s=min(up[i][j],(r[i][j]-l[i][j]+1))*min(up[i][j],(r[i][j]-l[i][j]+1));//这里主要是求正方形,悬线法的强大无法真正体现 
            ans=max(ans,s);//矩形的话直接就 ans=max(ans,up[i][j]*(r[i][j]-l[i][j]+1)) 
        }
        cout<<sqrt(ans);
        return 0;
    }
  • 相关阅读:
    LTPA Cookie原理
    如何对更改internet密码所需的缓存时间进行调整?
    Freemem eclipse查看内存的小插件
    Java中static、final用法小结
    MANIFEST.MF内容属性名详细解释
    Java程序员的良药:应用程序的开发技巧
    spring struts2 ibatis框架整合开发
    java中静态代码块的用法 static用法详解 类的加载顺序
    从svn上直接导入项目到workspace中
    Eclipse自动生成UML图 Green UML和ModelGoon(直接推拽)
  • 原文地址:https://www.cnblogs.com/wdxxz3274/p/12070080.html
Copyright © 2011-2022 走看看