首页 > 代码库 > bzoj1047: [HAOI2007]理想的正方形

bzoj1047: [HAOI2007]理想的正方形

好神的单调栈啊。。。

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define rep(i,s,t) for(register int i=s;i<=t;i++)#define dwn(i,s,t) for(register int i=s;i>=t;i--)#define clr(x,c) memset(x,c,sizeof(x))int read(){    int x=0;char c=getchar();    while(!isdigit(c)) c=getchar();    while(isdigit(c)) x=x*10+c-‘0‘,c=getchar();    return x;} const int nmax=1005;const int inf=0x7f7f7f7f;int a[nmax][nmax],n,m,b;int q[nmax],mx[nmax][nmax],mn[nmax][nmax],ans[nmax],res[nmax];void solve(){    rep(i,1,n){        int l=1,r=0;        rep(j,1,m) {            if(q[l]<=j-b) l++;            while(l<=r&&a[i][q[r]]<=a[i][j]) r--;            q[++r]=j;            if(j>=b) mx[i][j]=a[i][q[l]];        }        l=1,r=0;        rep(j,1,m){            if(q[l]<=j-b) l++;            while(l<=r&&a[i][q[r]]>=a[i][j]) r--;            q[++r]=j;            if(j>=b) mn[i][j]=a[i][q[l]];        }    }    /*rep(i,1,n) {        rep(j,b,m) printf("%d ",mx[i][j]);printf("\n");    }    printf("\n");    rep(i,1,n){        rep(j,b,m) printf("%d ",mn[i][j]);printf("\n");    }    printf("\n");*/}void mins(int &a,int b){    if(a>b) a=b;}void work(){    int ret=inf;    rep(j,b,m){        int l=1,r=0;        rep(i,1,n) {            if(q[l]<=i-b) l++;            while(l<=r&&mx[q[r]][j]<=mx[i][j]) r--;            q[++r]=i;            if(i>=b) ans[i]=mx[q[l]][j];        }        l=1,r=0;        rep(i,1,n) {            if(q[l]<=i-b) l++;            while(l<=r&&mn[q[r]][j]>=mn[i][j]) r--;            q[++r]=i;            if(i>=b) res[i]=mn[q[l]][j];        }        rep(i,b,n) mins(ret,ans[i]-res[i]);    }    printf("%d\n",ret);}int main(){    n=read(),m=read(),b=read();    rep(i,1,n) rep(j,1,m) a[i][j]=read();    solve();work();    return 0;}

  

1047: [HAOI2007]理想的正方形

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 2702  Solved: 1465
[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<=100

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

 

Source

 
[Submit][Status][Discuss]

bzoj1047: [HAOI2007]理想的正方形