zoukankan      html  css  js  c++  java
  • [LUOGU] P2716 和谐的雪花

    https://www.luogu.org/problemnew/show/P2716

    给出一个n*m的矩形,求里面边长最小的正方形,使得该正方形内最大值与最小值的差大于等于给定的K。

    第一反应是二分答案+二维RMQ,时间复杂度是能过的,O(nlognlognlogn),空间O(n*nlogn)。

    (待补充)

    考虑一个看起来不怎么优秀的O(n^3)做法,实际上是可以通过本题的。

    设左上角在(i,j)的边长为k的正方形的最大值为f[i][j][k],最小值g[i][j][k],转移方程显然有f[i][j][k]=max{f[i][j][k-1],f[i+1][j][k-1],f[i][j+1][k-1],f[i+1][j+1][k-1]},g同理。

    如果在顺推时找到了一个f[i][j][k]-g[i][j][k]>=K,那么这个边长k一定是最小的了,

    但是这样空间受限是吃不消的,注意到转移中第三维k是单调转移的,可以用适当的转移方式(也就是正常顺推)缩掉这一维。

    空间复杂度O(n^2),时间复杂度O(n^3),卡常可不开O2通过。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    inline int rd(){
      int ret=0,f=1;char c;
      while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
      while(isdigit(c))ret=ret*10+c-'0',c=getchar();
      return ret*f;
    }
    
    const int MAXN=512;
    
    int n,m,q;
    int a[MAXN*MAXN];
    int f[MAXN*MAXN],g[MAXN*MAXN];
    int main(){
      n=rd();m=rd();q=rd();
      for(register int i=1;i<=n;i++)
        for(register int j=1;j<=m;j++)
          f[(i<<9)+j]=g[(i<<9)+j]=a[(i<<9)+j]=rd();
      int up=min(n,m)-1;
      for(register int k=1;k<=up;k++)
        for(register int i=1;i<=n-k;i++)
          for(register int j=1;j<=m-k;j++){
            f[(i<<9)+j]=max(f[(i<<9)+j],max(f[(i+1<<9)+j],max(f[(i<<9)+j+1],f[(i+1<<9)+j+1])));
            g[(i<<9)+j]=min(g[(i<<9)+j],min(g[(i+1<<9)+j],min(g[(i<<9)+j+1],g[(i+1<<9)+j+1])));
            if(f[(i<<9)+j]-g[(i<<9)+j]>=q) return printf("%d
    ",k+1),0;
          }
      puts("-1");
      return 0;
    }

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9343226.html

  • 相关阅读:
    英语四级day1
    Hadoop实战
    Red Hat
    SQL Cookbook
    Java改错学习法
    Java程序设计经典300例
    Git
    ColorOS和MIUI双系统安装笔记
    深入浅出MySQL数据库开发、优化于管理维护
    剑指Offer名企面试官精讲典型编程题
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9343226.html
Copyright © 2011-2022 走看看