1. 程式人生 > >BZOJ 1047: [HAOI2007]理想的正方形

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

als 整數和 inf smart 最小 pre 一行 zoj cpp

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\n",ans);
	return 0;
}

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