码迷,mamicode.com
首页 > 其他好文 > 详细

1047: [HAOI2007]理想的正方形——二维单调队列

时间:2015-05-29 10:05:06      阅读:115      评论:0      收藏:0      [点我收藏+]

标签:

http://www.lydsy.com/JudgeOnline/problem.php?id=1047

对每一行维护一个单调队列,保存在lmin[][],lmax[][]
然后对每一列维护一个单调队列,最后n*n枚举

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define clr(a,b) memset(a,b,sizeof(a))
const int maxn = 1100;
const int INF = 0x3f3f3f3f;
using namespace std;
int n,m,k;
int que[maxn],a[maxn][maxn];
int lmin[maxn][maxn],lmax[maxn][maxn];
int rmin[maxn][maxn],rmax[maxn][maxn];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif // ONLINE_JUDGE
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            scanf("%d",&a[i][j]);
        }
    }
    int front,rear;
    for(int i=1;i<=n;++i){
        front=rear=1;
        for(int j=1;j<=m;++j){
            while(front<rear&&a[i][que[rear-1]]>a[i][j]) rear--;
            que[rear++]=j;
            while(front<rear&&j-que[front]+1>k) front++;
            if(j>=k) lmin[i][j-k+1]=a[i][que[front]];

        }
        front=rear=1;
        for(int j=1;j<=m;++j){
            while(front<rear&&a[i][que[rear-1]]<a[i][j]) rear--;
            que[rear++]=j;
            while(front<rear&&j-que[front]+1>k) front++;
            if(j>=k) lmax[i][j-k+1]=a[i][que[front]];
        }
    }
    for(int j=1;j<=m-k+1;++j){//列
        front=rear=1;
        for(int i=1;i<=n;++i){//行
            while(front<rear&&lmin[que[rear-1]][j]>lmin[i][j]) rear--;
            que[rear++]=i;
            while(front<rear&&i-que[front]+1>k) front++;
            if(i>=k) rmin[j][i-k+1]=lmin[que[front]][j];
        }
        front=rear=1;
        for(int i=1;i<=n;++i){
            while(front<rear&&lmax[que[rear-1]][j]<lmax[i][j]) rear--;
            que[rear++]=i;
            while(front<rear&&i-que[front]+1>k) front++;
            if(i>=k) rmax[j][i-k+1]=lmax[que[front]][j];
        }
    }
    int ans=INF;
    for(int i=1;i<=m-k+1;++i){
        for(int j=1;j<=n-k+1;++j){
            if(rmax[i][j]!=-1)
            ans=min(ans,rmax[i][j]-rmin[i][j]);
        }
    }
    printf("%d\n",ans);
    return 0;
}

1047: [HAOI2007]理想的正方形——二维单调队列

标签:

原文地址:http://blog.csdn.net/u014141559/article/details/46136953

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!