zoukankan      html  css  js  c++  java
  • BZOJ 1047: [HAOI2007]理想的正方形( 单调队列 )

    单调队列..先对每一行扫一次维护以每个点(x, y)为结尾的长度为n的最大最小值.然后再对每一列扫一次, 在之前的基础上维护(x, y)为结尾的长度为n的最大最小值. 时间复杂度O(ab)

    (话说还是deque2048ms快..list3572ms慢死了)

    #include<bits/stdc++.h>
    
    using namespace std;
    
    const int maxn = 1009;
    
    int X[maxn][maxn], R, C, N;
    int MN[maxn][maxn], MX[maxn][maxn];
    deque<int> MIN, MAX;
    
    int main() {
    	
    	cin >> R >> C >> N;
    	for(int i = 0; i < R; i++)
    	    for(int j = 0; j < C; j++)
    	        scanf("%d", &X[i][j]);
    	
    	for(int i = 0; i < R; i++) {
    		MIN.clear(); MAX.clear();
    		for(int j = 0; j < C; j++) {
    			while(!MIN.empty() && MIN.front() + N <= j) MIN.pop_front();
    			while(!MAX.empty() && MAX.front() + N <= j) MAX.pop_front();
    		    while(!MIN.empty() && X[i][MIN.back()] >= X[i][j]) MIN.pop_back();
    		    while(!MAX.empty() && X[i][MAX.back()] <= X[i][j]) MAX.pop_back();
    		    MIN.push_back(j);
    			MAX.push_back(j);
    			if(j + 1 >= N) {
    				MN[i][j - N + 1] = X[i][MIN.front()];
    				MX[i][j - N + 1] = X[i][MAX.front()];
    			}
    		}
    	}
    	
    	int ans = 2000000000;
    	for(int j = 0; j + N <= C; j++) {
    		MIN.clear(); MAX.clear();
    		for(int i = 0; i < R; i++) {
    			while(!MIN.empty() && MIN.front() + N <= i) MIN.pop_front();
    			while(!MAX.empty() && MAX.front() + N <= i) MAX.pop_front();
    			while(!MIN.empty() && MN[MIN.back()][j] >= MN[i][j]) MIN.pop_back();
    			while(!MAX.empty() && MX[MAX.back()][j] <= MX[i][j]) MAX.pop_back();
    			MIN.push_back(i);
    			MAX.push_back(i);
    			if(i + 1 >= N)
    			    ans = min(ans, MX[MAX.front()][j] - MN[MIN.front()][j]);
    		}
    	}
    	printf("%d
    ", ans);
    	
    	return 0;
    }
    

      

    1047: [HAOI2007]理想的正方形

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2058  Solved: 1093
    [Submit][Status][Discuss]

    Description

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

    Input

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

    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

    HINT

    问题规模

    (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

    Source

  • 相关阅读:
    Opencv算法运行时间
    markdown转换为html
    jQuery类名添加click方法
    box-sizing 盒子模型不改变大小
    nodejs 发送get 请求 获取博客园文章列表
    6、Python3中的常用正则表达式
    5、Python3打印函数名之__name__属性
    4、reduce函数工具的使用
    3、Python字符编码区分utf-8和utf-8-sig
    9、QT QLineEdit 密码模式
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4731311.html
Copyright © 2011-2022 走看看