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 }
  • 相关阅读:
    课堂Scrum站立会议演示
    每周工作进度及工作量统计
    连连看的设计与实现——四人小组项目(GUI)
    连连看的设计与实现——四人小组项目(NABCD)
    用户模板和用户场景
    对MySQL 存储过程中乱码的破解
    MySQL数据库同步的实现
    解决MySQL无法远程访问的3方案
    使用SQL Server 2014内存数据库时需要注意的地方
    navicat for sql server中文版|SQL Server管理及开发工具(Navicat for SQL Server)下载 v11.2.13
  • 原文地址:https://www.cnblogs.com/InWILL/p/9337841.html
Copyright © 2011-2022 走看看