博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 1047 理想的正方形(单调队列)
阅读量:6279 次
发布时间:2019-06-22

本文共 1059 字,大约阅读时间需要 3 分钟。

题目链接:

题意:给出一个n*m的矩阵。在所有K*K的子矩阵中,最大最小差值最小的是多少?

思路:枚举每一行,枚举每一列,(r,c),将(r-K+1,c-K+1)中的数字插入到单调队列中保存(这里设置两个单调队列,一个最大一个最小)。每次计算以(r,c)为右下角的子矩阵的值时,判断队列头元素的列数是不是大于等于c-K+1,否则删掉队头。插入时,比如维护最小的单调队列,要判断队尾的元素是不是小于当前元素,不小于则删掉队尾。

 

int n,m,K;
pair<int,int> Q1[N],Q2[N];
int head1,tail1,head2,tail2;
int c[N][N];
pair<int,int> get(int r1,int r2,int t)
{
    int Min=INF,Max=-INF,i;
    FOR(i,r1,r2)
    {
        Min=min(Min,c[i][t]);
        Max=max(Max,c[i][t]);
    }
    return MP(Min,Max);
}
int cal(int r)
{
    head1=tail1=head2=tail2=0;
    int i,x,y,ans=INF;
    pair<int,int> p;
    for(i=1;i<=m;i++)
    {
        p=get(r-K+1,r,i);
        x=p.first;
        y=p.second;
        while(head1<tail1&&Q1[tail1-1].second>=x) tail1--;
        Q1[tail1++]=MP(i,x);
        while(head2<tail2&&Q2[tail2-1].second<=y) tail2--;
        Q2[tail2++]=MP(i,y);
        if(i<K) continue;
        while(Q1[head1].first<i-K+1) head1++;
        x=Q1[head1].second;
        while(Q2[head2].first<i-K+1) head2++;
        y=Q2[head2].second;
        if(y-x<ans) ans=y-x;
    }
    return ans;
}
int main()
{
    RD(n,m,K);
    int i,j;
    FOR1(i,n) FOR1(j,m) RD(c[i][j]);
    int ans=INF,temp;
    for(i=K;i<=n;i++)
    {
        temp=cal(i);
        if(temp<ans) ans=temp;
    }
    PR(ans);
    return 0;
}

 

转载地址:http://kryva.baihongyu.com/

你可能感兴趣的文章
话说模式匹配(5) for表达式中的模式匹配
查看>>
《锋利的SQL(第2版)》——1.7 常用函数
查看>>
《Arduino家居安全系统构建实战》——1.5 介绍用于机器学习的F
查看>>
jquery中hover()的用法。简单粗暴
查看>>
线程管理(六)等待线程的终结
查看>>
spring boot集成mongodb最简单版
查看>>
DELL EqualLogic PS存储数据恢复全过程整理
查看>>
《Node.js入门经典》一2.3 安装模块
查看>>
《Java 开发从入门到精通》—— 2.5 技术解惑
查看>>
Linux 性能诊断 perf使用指南
查看>>
实操分享:看看小白我如何第一次搭建阿里云windows服务器(Tomcat+Mysql)
查看>>
Sphinx 配置文件说明
查看>>
数据结构实践——顺序表应用
查看>>
python2.7 之centos7 安装 pip, Scrapy
查看>>
机智云开源框架初始化顺序
查看>>
Spark修炼之道(进阶篇)——Spark入门到精通:第五节 Spark编程模型(二)
查看>>
一线架构师实践指南:云时代下双活零切换的七大关键点
查看>>
ART世界探险(19) - 优化编译器的编译流程
查看>>
玩转Edas应用部署
查看>>
music-音符与常用记号
查看>>