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]
posted @ 2016-09-10 14:28  BBChq  阅读(170)  评论(0编辑  收藏  举报