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

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 4075  Solved: 2277
    [Submit][Status][Discuss]

    Description

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

    Input

      第一行为3个整数,分别表示a,b,n的值第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数。每
    行相邻两数之间用一空格分隔。
    100%的数据2<=a,b<=1000,n<=a,n<=b,n<=1000

    Output

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

    Sample Input

    5 4 2
    1 2 5 6
    0 17 16 0
    16 17 2 1
    2 10 2 1
    1 2 2 2

    Sample Output

    1
     
    二维单调队列
    先计算每行前n个点的最大值和最小值,用单调队列维护。
    然后按列的顺序计算每个点作为右下角时,矩阵的最大值和最小值。
    简单来说,就是多次运用单调队列,将二维矩阵压缩为一维矩阵求解
     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 
     5 const int MAXN=1000+5;
     6 const int INF=0x7fffffff;
     7 
     8 int a,b,n,ans=INF;
     9 int s[MAXN][MAXN],mx[MAXN][MAXN],mn[MAXN][MAXN];
    10 int val[MAXN],pos[MAXN],x[MAXN],y[MAXN];
    11 
    12 int main()
    13 {
    14     scanf("%d %d %d",&a,&b,&n);
    15     for(int i=1;i<=a;i++)
    16         for(int j=1;j<=b;j++)
    17             scanf("%d",&s[i][j]);
    18     int l,r;
    19     for(int i=1;i<=a;i++)
    20     {
    21         l=1,r=1;
    22         for(int j=1;j<=b;j++)
    23         {
    24             while(l<r&&val[r-1]<=s[i][j]) r--;
    25             val[r]=s[i][j];pos[r]=j;r++;
    26             if(pos[l]==j-n) l++;
    27             if(j>=n) mx[i][j]=val[l];
    28         }
    29         l=1,r=1;
    30         for(int j=1;j<=b;j++)
    31         {
    32             while(l<r&&val[r-1]>=s[i][j]) r--;
    33             val[r]=s[i][j];pos[r]=j;r++;
    34             if(pos[l]==j-n) l++;
    35             if(j>=n) mn[i][j]=val[l];
    36         }
    37     }
    38     for(int i=n;i<=b;i++)
    39     {
    40         l=1,r=1;
    41         for(int j=1;j<=a;j++)
    42         {
    43             while(l<r&&val[r-1]<=mx[j][i]) r--;
    44             val[r]=mx[j][i];pos[r]=j;r++;
    45             if(pos[l]==j-n) l++;
    46             if(j>=n) x[j]=val[l];
    47         }
    48         l=1,r=1;
    49         for(int j=1;j<=a;j++)
    50         {
    51             while(l<r&&val[r-1]>=mn[j][i]) r--;
    52             val[r]=mn[j][i];pos[r]=j;r++;
    53             if(pos[l]==j-n) l++;
    54             if(j>=n) y[j]=val[l];
    55         }
    56         for(int i=n;i<=a;i++) ans=min(ans,x[i]-y[i]);
    57     }
    58     printf("%d
    ",ans);
    59     return 0;
    60 }
  • 相关阅读:
    Castle Windsor 学习-----Installer的几种安装方式
    asp.net mvc源码分析-Route的GetRouteData
    查看iis对应w3wp.exe显示的进程ID号(转载)
    jvisualvm安装Visual GC插件
    Modelsimse10.4如何编译altera库文件以支持IP仿真
    sublime text3 配置使用
    Modelsim调用用do脚本自动化仿真
    Quartus16.0如何使用TCL脚本
    Java中使用Timer和TimerTask实现多线程
    框架导论
  • 原文地址:https://www.cnblogs.com/InWILL/p/9337841.html
Copyright © 2011-2022 走看看