zoukankan      html  css  js  c++  java
  • BZOJ1047: [HAOI2007]理想的正方形(单调队列)

    有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值
    的差最小。

    题解:以前居然不会做????

       这数据范围直接暴力就好了 先维护一下每行每n个数的最大最小值

       再像滑窗一样每n行的统计一下答案就行了

    #include <bits/stdc++.h>
    using namespace std;
    
    int n, m, k;
    int a[1005][1005];
    int zd[1005]; int did[1005];
    int zx[1005]; int xid[1005];
    int mx[1005][1005];
    int mi[1005][1005];
    
    int main()
    {
        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]);
    
        for(int i = 1; i <= n; i++)
        {
            int top1 = 1, tail1 = 0;
            int top2 = 1, tail2 = 0;
            int cnt = 0;
            for(int j = 1; j <= m; j++)
            {
                zd[++tail1] = a[i][j]; did[tail1] = j;
                while(top1 != tail1 && zd[tail1] >= zd[tail1 - 1]) tail1--, zd[tail1] = a[i][j], did[tail1] = j;
                while(j - did[top1] + 1 > k) top1++;
    
                zx[++tail2] = a[i][j]; xid[tail2] = j;
                while(top2 != tail2 && zx[tail2] <= zx[tail2 - 1]) tail2--, zx[tail2] = a[i][j], xid[tail2] = j;
                while(j - xid[top2] + 1 > k) top2++;
                if(j >= k) mx[i][++cnt] = zd[top1], mi[i][cnt] = zx[top2];
            }
        }
    
        int ans = 1e9;
        for(int i = 1; i <= m - k + 1; i++)
        {
            int top1 = 1, tail1 = 0;
            int top2 = 1, tail2 = 0;
            for(int j = 1; j <= n; j++)
            {
                zd[++tail1] = mx[j][i]; did[tail1] = j;
                while(top1 != tail1 && zd[tail1] >= zd[tail1 - 1]) tail1--, zd[tail1] = mx[j][i], did[tail1] = j;
                while(j - did[top1] + 1 > k) top1++;
    
                zx[++tail2] = mi[j][i]; xid[tail2] = j;
                while(top2 != tail2 && zx[tail2] <= zx[tail2 - 1]) tail2--, zx[tail2] = mi[j][i], xid[tail2] = j;
                while(j - xid[top2] + 1 > k) top2++;
    
                if(j >= k) ans = min(ans, zd[top1] - zx[top2]);
            }
        }
        printf("%d
    ", ans);
        return 0;
    }
    View Code
  • 相关阅读:
    简单的php socket 实例
    正则表达式语法
    js 固话正则
    php性能剖析的几款软件
    mysql基准测试
    mysql事务
    PHP字符串函数
    Git的使用---4.git的基本使用
    Git的使用---3.git的配置
    Git的使用---2.git的安装
  • 原文地址:https://www.cnblogs.com/lwqq3/p/9832672.html
Copyright © 2011-2022 走看看