列表

详情


NC50535. 理想的正方形

描述

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

输入描述

第一行为三个整数,分别表示a,b,n的值;
第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数。

输出描述

输出仅一个整数,为矩阵中所有「正方形区域中的最大整数和最小整数的差值」的最小值。

示例1

输入:

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

输出:

1

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 163ms, 内存消耗: 12360K, 提交时间: 2022-08-14 00:54:40

#include<iostream>
using namespace std;
const int N = 1010;
int w[N][N], row_min[N][N], row_max[N][N];
int st[N];
int n, m, k;
void get_min(int a[], int b[], int n)  //获取最小值, 
{
    int l = 0, r = -1;
    for(int i = 1; i <= n; i++){
        while(l <= r && i - st[l] >= k)l++;
        while(l <= r && a[i] <= a[st[r]])r--;
        st[++r] = i;
        b[i] = a[st[l]];
    }
}
void get_max(int a[], int b[], int n)   //获取最大值
{
    int l = 0, r = -1;
    for(int i = 1; i <= n; i++){
        while(l <= r && i - st[l] >= k)l++;
        while(l <= r && a[i] >= a[st[r]])r--;
        st[++r] = i;
        b[i] = a[st[l]];
    }
}
int main()
{
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            scanf("%d", &w[i][j]);
    for(int i = 1; i <= n; i++){
        get_min(w[i], row_min[i], m);
        get_max(w[i], row_max[i], m);
    }
    
    int ans = 1e9;
    int a[N], b[N], c[N];
    for(int i = k; i <= m; i++){
        for(int j = 1; j <= n; j++) a[j] = row_max[j][i];
        get_max(a, b, n);
        for(int j = 1; j <= n; j++) a[j] = row_min[j][i];
        get_min(a, c, n);
        
        for(int j = k; j <= n; j++) ans = min(ans, b[j] - c[j]);
    }
    cout << ans << endl;
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 864ms, 内存消耗: 6136K, 提交时间: 2020-06-01 10:44:06

#include<bits/stdc++.h>
using namespace std;
struct Container
{
	deque<int> qmin;
	deque<int> qmax;
	Container():qmin(),qmax(){}
	void push(int n)
	{
		while(qmin.size()&&qmin.back()>n) qmin.pop_back();
		qmin.push_back(n);
		while(qmax.size()&&qmax.back()<n) qmax.pop_back();
		qmax.push_back(n);
	}
	void  pop(int n)
	{
		if(qmin.size()&&qmin.front()==n) qmin.pop_front();
		if(qmax.size()&&qmax.front()==n) qmax.pop_front();
	}
	int max()
	{
		return qmax.front();
	}
	int min()
	{
      return qmin.front();
	}
};
int main()
{
	int a,b,n;
	cin>>a>>b>>n;
	vector<vector<int> > mat(a,vector<int>(b));
	for(auto &v:mat)
	for(auto &i:v)
	cin>>i;
	vector<Container> Q(b);
	int ans=0x3f3f3f3f;
	for(int i=0;i<a;i++)
	{
		if(i>=n)
		for(int j=0;j<b;j++)
		Q[j].pop(mat[i-n][j]);
		for(int j=0;j<b;j++)
		Q[j].push(mat[i][j]);
		if(i<n-1) continue;
		Container C;
		for(int j=0;j<b;j++)
		{
			if(j-n>=0)
			C.pop(Q[j-n].max()),C.pop(Q[j-n].min());
			C.push(Q[j].max()),C.push(Q[j].min());
			if(j>=n-1)
			ans=min(ans,C.max()-C.min());
		}
	}
	cout<<ans<<endl;
}

上一题