zoukankan      html  css  js  c++  java
  • [HAOI2007]理想的正方形

    题目描述

    有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小。

    输入输出格式

    输入格式:

    第一行为3个整数,分别表示a,b,n的值

    第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数。每行相邻两数之间用一空格分隔。

    输出格式:

    仅一个整数,为a*b矩阵中所有“n*n正方形区域中的最大整数和最小整数的差值”的最小值。

    输入输出样例

    输入样例#1:
    5 4 2
    1 2 5 6
    0 17 16 0
    16 17 2 1
    2 10 2 1
    1 2 2 2
    
    输出样例#1:
    1

    说明

    问题规模

    (1)矩阵中的所有数都不超过1,000,000,000

    (2)20%的数据2<=a,b<=100,n<=a,n<=b,n<=10

    (3)100%的数据2<=a,b<=1000,n<=a,n<=b,n<=100

    这题大多用的是单调队列或二维线段树(卡常)

    但标签有dp

    于是用dp的方法

    f[i][j][k]表示左上(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])

    复杂度为O(abn)会超时

    这里用倍增,f[i][j][k]表示左上(i,j)边长为2^k

    f[i][j][k]=max(f[i][j][k-1],f[i+2^(k-1)][j][k-1],f[i][j+2^(k-1)][k-1],f[i+2^(k-1)][j+2^(k-1)][k-1])

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 int f1[2001][2001],f2[2001][2001],ans,a,b,n;
     8 int logn;
     9 int query(int x,int y)
    10 {int maxv=0,minv=0;
    11     maxv=max(f1[x][y],max(f1[x+n-(1<<logn)][y],max(f1[x][y+n-(1<<logn)],f1[x+n-(1<<logn)][y+n-(1<<logn)])));
    12     minv=min(f2[x][y],min(f2[x+n-(1<<logn)][y],min(f2[x][y+n-(1<<logn)],f2[x+n-(1<<logn)][y+n-(1<<logn)])));
    13   return maxv-minv;
    14 }
    15 int main()
    16 {int i,j,k;
    17     cin>>a>>b>>n;
    18     logn=log2(n);
    19     for (i=1;i<=a;i++)
    20     {
    21         for (j=1;j<=b;j++)
    22         scanf("%d",&f1[i][j]),f2[i][j]=f1[i][j];
    23     }
    24      for (k=0;k<logn;k++)
    25      {
    26          for (i=1;i+(1<<k)<=a;i++)
    27          {
    28              for (j=1;j+(1<<k)<=b;j++)
    29               {
    30                   f1[i][j]=max(f1[i][j],max(f1[i+(1<<k)][j],max(f1[i][j+(1<<k)],f1[i+(1<<k)][j+(1<<k)])));
    31                   f2[i][j]=min(f2[i][j],min(f2[i+(1<<k)][j],min(f2[i][j+(1<<k)],f2[i+(1<<k)][j+(1<<k)])));
    32              }
    33          }
    34      }
    35      ans=2e9;
    36      for (i=1;i<=a-n+1;i++)
    37      for (j=1;j<=b-n+1;j++)
    38      ans=min(ans,query(i,j));
    39     cout<<ans;
    40 }
  • 相关阅读:
    AS将一个项目导入到另一个项目中
    Android Studio出现:Cause: unable to find valid certification path to requested target
    小米手机Toast带app名称
    PopupWindow 点击外部区域无法关闭的问题
    EditText inputType类型整理
    Fragment通过接口回调向父Activity传值
    Android selector一些坑
    Installation failed with message Failed to commit install session 634765663 with command cmd package
    旷视上海研究院机器人方向招聘
    语义SLAM的数据关联和语义定位(四)多目标测量概率模型
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7340795.html
Copyright © 2011-2022 走看看