zoukankan      html  css  js  c++  java
  • bzoj1047理想的正方形

    题目链接 

    纪念又双叒叕的一道暴力碾标算的题
    我们考虑纯暴力
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int a,b,n;
    int map[1010][1010];
    int ans=0x3f3f3f3f;
    int main()
    {
     scanf("%d%d%d",&a,&b,&n);
     for(int i=1;i<=a;i++)
       for(int j=1;j<=b;j++)
      scanf("%d",&map[i][j]);
        for(int i=1;i+n-1<=a;i++)
          for(int j=1;j+n-1<=b;j++){
      int maxx=0,minn=0x3f3f3f3f;
         for(int l=i;l<=n+i-1;l++)
              for(int r=j;r<=n+j-1;r++)
                maxx=max(maxx,map[l][r]),
                minn=min(minn,map[l][r]);
      ans=min(ans,maxx-minn);
        }
        printf("%d",ans);
        return 20020902;
    }
    然后显然,果断$TLE$
    那么我们考虑怎么优化暴力
    别跟我提什么数据结构啊,单调队列
    本小可爱一个也不会
    我们回头看看这两道题 洛谷P2038   洛谷P2280
    这两道题也是矩阵,然后我们是用的维护二维前缀和来找的在一个矩形内的某些数值
    那么,这道题是不是也可以类似的做呢?
    由于询问的都是正方形,
    我们可以预处理出来
    所有正方形的最大最小值
    ($ps:$从$(1,1)$开始计数)
    定义$maxx[i][j][k]$表示以$(i,j)$为左上端点,然后边长为$k$的正方形最大值,$minn[i][j][k]$表示最小。
    通过类比上两道题,还有画图,得出
    $$maxx[i][j][k]=max(max(maxx[i][j][k-1],maxx[i+1][j+1][k-1]),max(maxx[i][j+1][k-1],maxx[i+1][j][k-1]))$$
    $$minn[i][j][k]=min(min(minn[i][j][k-1],minn[i+1][j+1][k-1]),min(minn[i][j+1][k-1],minn[i+1][j][k-1]))$$
    所以,我们可以求出来$maxx[][][n],minn[][][n]$
    然后枚举左上角端点然后更新答案就行

    别以为这样就好了
    您写完了之后本地编译了么?
    是不是编译未成功?
    因为$maxx,minn$这样要开$1001*1001*1001=1e9$辣么大的数组
    显然开不下啊$qwq$
    那怎么办?
    凉拌啊!
    发现我们推$maxx,minn$的时候,每次只涉及到$k,k-1$,并且只涉及到$i+1,j+1,i,j$这几个东东,所以可以类似滚动数组优化,滚掉$k$这一维
    然后又是省选题
    开个$O2$也没什么大不了的
    其实是本宝宝懒得写优化了
    上代码:
    看,连$1kb$都不到
    真是暴力碾标算的好题啊$qwq$
    // luogu-judger-enable-o2
    #pragma GCC optimize (2)
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int a,b,n;
    int map[1010][1010];
    int maxx[1010][1010];
    int minn[1010][1010];
    int ans=0x3f3f3f3f;
    int main()
    {
        scanf("%d%d%d",&a,&b,&n);
        for(int i=1;i<=a;i++)
          for(int j=1;j<=b;j++)
            scanf("%d",&map[i][j]),
            maxx[i][j]=minn[i][j]=map[i][j];
        for(int k=2;k<=n;k++)
          for(int i=1;i+k<=a+1;i++)
            for(int j=1;j+k<=b+1;j++)
              maxx[i][j]=max(max(maxx[i][j],maxx[i+1][j+1]),max(maxx[i][j+1],maxx[i+1][j])),
              minn[i][j]=min(min(minn[i][j],minn[i+1][j+1]),min(minn[i][j+1],minn[i+1][j])),
              ans=k==n?min(ans,maxx[i][j]-minn[i][j]):0x3f3f3f3f;
        printf("%d",ans);
        return 0;
    }
    /*
    5   4   2
    1   2   5   6
    0   17  16  0
    16  17  2   1
    2   10  2   1
    1   2   2   2
    */
  • 相关阅读:
    关于一个标准的poi下载文件模板 可拿来来直接使用
    关于史上最简单的导出(导出excal)
    关于spring MVC的面试题
    关于响应式布局(pc端访问自适应 手机端访问自适应)
    密码生成器
    关于poi的导出(POI)
    关于MUI一个很实用的前端框架
    (转载)插画版Kubernetes指南(小孩子也能看懂的kubernetes教程)
    (转载)Python tips: 什么是*args和**kwargs?
    python编程中的if __name__ == 'main': 的作用和原理
  • 原文地址:https://www.cnblogs.com/arcturus/p/9412851.html
Copyright © 2011-2022 走看看