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

    https://loj.ac/problem/10182

    题目描述

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

    思路

      我们可以先想办法把题目简单化,显然我们可以用单调队列一遍扫过去求出以(i)为左端点的连续的(n)个数的最大值和最小值,再考虑在列上思考,类似的,我们可以在求出来的最大和最小值的矩阵内按列(dp),求出(n)列中的最值,这也可以一遍实现,这样复杂度为(O(ab))

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e3+10;
    
    int read()
    {
    	int res=0,w=1;
    	char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){res=(res<<3)+(res<<1)+(ch^48);ch=getchar();}
    	return res*w;
    }
    
    int mp[N][N],f_max[N][N],f_min[N][N],f[N][N];
    int q[N];
    int main()
    {
    	int a=read(),b=read(),n=read();
    	for(int i=1;i<=a;i++)
    		for(int j=1;j<=b;j++)
    			mp[i][j]=read();
    	int head=0,tail=0;
    	for(int i=1;i<=a;i++)
    	{
    		head=1,tail=0;
    		for(int j=1;j<=b;j++)
    		{
    			while(head<=tail&&j-q[head]>=n)head++;
    			while(head<=tail&&mp[i][q[tail]]>=mp[i][j])tail--;
    			q[++tail]=j;
    			if(j>=n)f[i][j-n+1]=mp[i][q[head]];
    		}
    	}
    	for(int i=1;i<=b;i++)
    	{
    		head=1,tail=0;
    		for(int j=1;j<=a;j++)
    		{
    			while(head<=tail&&j-q[head]>=n)head++;
    			while(head<=tail&&f[q[tail]][i]>=f[j][i])tail--;
    			q[++tail]=j;
    			if(j>=n)f_min[j-n+1][i]=f[q[head]][i];
    		}
    	}
    	for(int i=1;i<=a;i++)
    	{
    		head=1,tail=0;
    		for(int j=1;j<=b;j++)
    		{
    			while(head<=tail&&j-q[head]>=n)head++;
    			while(head<=tail&&mp[i][q[tail]]<=mp[i][j])tail--;
    			q[++tail]=j;
    			if(j>=n)f[i][j-n+1]=mp[i][q[head]];
    		}
    	}
    	for(int i=1;i<=b;i++)
    	{
    		head=1,tail=0;
    		for(int j=1;j<=a;j++)
    		{
    			while(head<=tail&&j-q[head]>=n)head++;
    			while(head<=tail&&f[q[tail]][i]<=f[j][i])tail--;
    			q[++tail]=j;
    			if(j>=n)f_max[j-n+1][i]=f[q[head]][i];
    		}
    	}
    	int ans=0x7fffffff;
    	for(int i=1;i<=a-n+1;i++)
    		for(int j=1;j<=b-n+1;j++)
    			ans=min(ans,f_max[i][j]-f_min[i][j]);
    	printf("%d
    ",ans);
    }
    
  • 相关阅读:
    关于PHP程序员技术职业生涯规划
    让PHP7达到最高性能的几个Tips
    php-fpm解读-进程管理的三种模式 及 worker进程、master进程详解
    CGI、FastCGI和php-fpm概念和区别
    什么是PHP7中的孤儿进程与僵尸进程,加上守护进程
    PHP 信号管理知识整理汇总
    PHP多进程---fork多个子进程,父进程阻塞与非阻塞
    锁存器、触发器和寄存器
    FPGA基础之锁存器与触发器的设计
    从CMOS到触发器(二)
  • 原文地址:https://www.cnblogs.com/fangbozhen/p/11852068.html
Copyright © 2011-2022 走看看