• BZOJ 1047: [HAOI2007]理想的正方形


    1047: [HAOI2007]理想的正方形

    Time Limit: 10 Sec  Memory Limit: 162 MB

    Submit: 3563  Solved: 1967

    [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

    题解

    先用单调队列求出点(i,j)向下n个数中的最大值和最小值,再用单调队列维护一个n*n矩阵中的最大值和最小值,求出n*n的矩阵最大值减最小值的最小值。

    代码

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    const int N=1005,inf=0x3f3f3f3f;
    int a,b,n,m,ans=inf;
    int map[N][N],mx[N][N],mn[N][N],qx[N],qn[N];
    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]);
    		}
    	}
    	int lx,rx,ln,rn;
    	for(int i=1;i<=b;i++){
    		lx=ln=1,rx=rn=0;
    		qx[lx]=qx[rx]=qx[ln]=qn[rn]=0;
    		for(int j=1;j<=n;j++){
    			while(lx<=rx&&map[j][i]>map[qx[rx]][i])rx--;
    			qx[++rx]=j;
    			while(ln<=rn&&map[j][i]<map[qn[rn]][i])rn--;
    			qn[++rn]=j;
    		}
    		for(int j=n;j<=a;j++){
    			while(lx<=rx&&qx[lx]<j-n+1)lx++;
    			while(lx<=rx&&map[j][i]>map[qx[rx]][i])rx--;
    			qx[++rx]=j;
    			mx[j-n+1][i]=map[qx[lx]][i];
    			while(ln<=rn&&qn[ln]<j-n+1)ln++;
    			while(ln<=rn&&map[j][i]<map[qn[rn]][i])rn--;
    			qn[++rn]=j;
    			mn[j-n+1][i]=map[qn[ln]][i];
    		}
    	}
    	for(int i=1;i<=a-n+1;i++){
    		lx=ln=1,rx=rn=0;
    		qx[lx]=qx[rx]=qn[ln]=qn[rn]=0;
    		for(int j=1;j<=n;j++){
    			while(lx<=rx&&mx[i][j]>mx[i][qx[rx]])rx--;
    			qx[++rx]=j;
    			while(ln<=rn&&mn[i][j]<mn[i][qn[rn]])rn--;
    			qn[++rn]=j;
    		}
    		for(int j=n;j<=b;j++){
    			while(lx<=rx&&qx[lx]<j-n+1)lx++;
    			while(lx<=rx&&mx[i][j]>mx[i][qx[rx]])rx--;
    			qx[++rx]=j;
    			while(ln<=rn&&qn[ln]<j-n+1)ln++;
    			while(ln<=rn&&mn[i][j]<mn[i][qn[rn]])rn--;
    			qn[++rn]=j;
    			ans=min(ans,mx[i][qx[lx]]-mn[i][qn[ln]]);
    		}
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
  • 相关阅读:
    [03]使用 VS2019 创建 ASP.NET Core Web 程序
    [02]为您的机器配置开发环境
    [01]从零开始学 ASP.NET Core 与 EntityFramework Core 课程介绍
    官宣 ! 52abp_Pro版本低调上线
    2019 年起如何开始学习 ABP 框架系列文章-开篇有益
    IIS配置Url重写实现http自动跳转https的重定向方法(100%解决)
    NanoFabric-ServiceFabric 操作手册
    将 ASP.NET Core 2.0 项目升级至 ASP.NET Core 2.1.3X
    ASP.Net Core 运行错误 Http Error 502.5 解决办法
    52ABP模板 ASP.Net Core 与 Angular的开源实例项目
  • 原文地址:https://www.cnblogs.com/chezhongyang/p/7703518.html
Copyright © 2020-2023  润新知