其他分享
首页 > 其他分享> > P2216 [HAOI2007]理想的正方形

P2216 [HAOI2007]理想的正方形

作者:互联网

题面

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

输入格式

第一行为 \(3\) 个整数,分别表示 \(a,b,n\) 的值。

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

输出格式

仅一个整数,为 \(a \times b\) 矩阵中所有“ \(n \times n\) 正方形区域中的最大整数和最小整数的差值”的最小值。

问题规模

矩阵中的所有数都不超过 \(1,000,000,000\)。

\(20\%\) 的数据 \(2 \le a,b \le 100,n \le a,n \le b,n \le 10\)。

\(100\%\) 的数据 \(2 \le a,b \le 1000,n \le a,n \le b,n \le 100\)。

思路

暴力

10分。

#include <bits/stdc++.h>
using namespace std;

int a, b, n, ma[1005][1005], ans = INT_MAX;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> a >> b >> n;
	for (int i = 1; i <= a; i++) {
		for (int j = 1; j <= b; j++) {
			cin >> ma[i][j];
		}
	}
	for (int i = 1; i <= a - n + 1; i++) {
		for (int j = 1; j <= a - n + 1; j++) {
			int maxv = INT_MIN, minv = INT_MAX;
			for (int k = i; k <= i + n - 1; k++) {
				for (int l = j; l <= j + n - 1; l++) {
					maxv = max(maxv, ma[k][l]);;
					minv = min(minv, ma[k][l]);
				}
			}
			ans = min(ans, maxv - minv);
		}
	}
	cout << ans << endl;

	return 0;
}

二维ST表

这道题比较难处理。

#include <bits/stdc++.h>
#define int long long
using namespace std;

int n,m,k,a[1005][1005],ans=INT_MAX;

namespace STTable {
	int maxv[1005][1005],minv[1005][1005],logg;

	int querymax(int x,int y){
		int mmax=0;
		mmax=max(maxv[x][y],max(maxv[x+k-(1<<logg)][y+k-(1<<logg)],max(maxv[x+k-(1<<logg)][y],maxv[x][y+k-(1<<logg)])));
		return mmax;
	}
	
	int querymin(int x,int y){
		int mmin=0;
		mmin=min(minv[x][y],min(minv[x+k-(1<<logg)][y+k-(1<<logg)],min(minv[x+k-(1<<logg)][y],minv[x][y+k-(1<<logg)])));
		return mmin;
	}
	
	int query(int x, int y) {
		return querymax(x,y)-querymin(x,y);
	}

	void init() {
		logg = log(k)/log(2);
		for(int s=0; s<logg; s++) {
			for(int i=1; i+(1<<s)<=n; i++) {
				for(int j=1; j+(1<<s)<=m; j++) {
					maxv[i][j]=max(maxv[i][j],max(maxv[i+(1<<s)][j+(1<<s)],max(maxv[i+(1<<s)][j],maxv[i][j+(1<<s)])));
					minv[i][j]=min(minv[i][j],min(minv[i+(1<<s)][j+(1<<s)],min(minv[i+(1<<s)][j],minv[i][j+(1<<s)])));
				}
			}
		}
	}
}

signed main(){
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>a[i][j];
			STTable::maxv[i][j]=a[i][j];
			STTable::minv[i][j]=a[i][j];
		}
	}
	STTable::init();
	for(int i=1;i<=n-k+1;i++){
		for(int j=1;j<=m-k+1;j++){
			ans=min(ans,STTable::query(i,j));
		}
	}
	cout<<ans<<endl;
}

\(100\) 分。

标签:le,int,maxv,times,HAOI2007,正方形,P2216,1005,100
来源: https://www.cnblogs.com/xiezheyuan/p/note-rem-p2216.html