• 洛谷P2216 [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,第一遍处理出行i内以j为端点的长度为n的区间内的最大值和最小值。

    第二遍DP,根据之前处理出的一维区间最值,DP出二维区间最值。

    然后枚举区间端点,找最优解。

    需要用单调队列优化

     1 /*by SilverN*/
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #include<vector>
     8 using namespace std;
     9 const int mxn=1010;
    10 int read(){
    11     int x=0,f=1;char ch=getchar();
    12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    13     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    14     return x*f;
    15 }
    16 int mp[mxn][mxn];
    17 int fmx[mxn][mxn],fmi[mxn][mxn];
    18 int dpmx[mxn][mxn],dpmi[mxn][mxn];
    19 int a,b,n;
    20 void work(){
    21     
    22 }
    23 int q1[mxn],hd1=0,tl1=0;
    24 int q2[mxn],hd2=0,tl2=0;
    25 int main(){
    26     a=read();b=read();n=read();
    27     int i,j;
    28     memset(fmi,0x3f,sizeof fmi);
    29     for(i=1;i<=a;i++){
    30         hd1=hd2=1;
    31         tl1=tl2=0;
    32         for(j=1;j<=b;j++){
    33             mp[i][j]=read();
    34             while(hd1<=tl1 && j-q1[hd1]>=n)hd1++;
    35             while(hd1<=tl1 && mp[i][j]>=mp[i][q1[tl1]]) tl1--;
    36             q1[++tl1]=j;
    37             fmx[i][j]=mp[i][q1[hd1]];
    38             //max
    39             while(hd2<=tl2 && j-q2[hd2]>=n)hd2++;
    40             while(hd2<=tl2 && mp[i][j]<=mp[i][q2[tl2]]) tl2--;
    41             q2[++tl2]=j;
    42             fmi[i][j]=mp[i][q2[hd2]];
    43             //min
    44         }
    45     }
    46     memset(dpmi,0x3f,sizeof dpmi);
    47     hd1=hd2=1;tl1=tl2=0;
    48     for(j=1;j<=b;j++){
    49         hd1=hd2=1;tl1=tl2=0;
    50         for(i=1;i<=a;i++){
    51             while(hd1<=tl1 && i-q1[hd1]>=n)hd1++;
    52             while(hd1<=tl1 && fmx[i][j]>=fmx[q1[tl1]][j])tl1--;
    53             q1[++tl1]=i;
    54             dpmx[i][j]=fmx[q1[hd1]][j];
    55             
    56             while(hd2<=tl2 && i-q2[hd2]>=n)hd2++;
    57             while(hd2<=tl2 && fmi[i][j]<=fmi[q2[tl2]][j])tl2--;
    58             q2[++tl2]=i;
    59             dpmi[i][j]=fmi[q2[hd2]][j];
    60             
    61         }
    62     }
    63     int ans=0x3f3f3f3f;
    64     for(i=n;i<=a;i++)
    65      for(j=n;j<=b;j++){
    66          ans=min(ans,dpmx[i][j]-dpmi[i][j]);
    67      }
    68     printf("%d
    ",ans);
    69     return 0;
    70 }
  • 相关阅读:
    es6-字符串常用方法
    新增行数据校验
    python-Django路由传参
    递归算法
    CSS动画效果
    克隆远程仓库
    添加git仓库
    滚动条——overflow:auto 自定义样式
    CSS——链接伪类选择器
    进程,线程,同步 ,异步
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/5982430.html
Copyright © 2020-2023  润新知