• bzoj1047[HAOI2007]理想的正方形


    bzoj1047[HAOI2007]理想的正方形

    题意:

    有一个a*b的整数组成的矩阵,求一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小。a,b≤1000,n≤100

    题解:

    做4次单调队列。先利用单调队列求出第i行第j列到第i行第j+n-1列的最大最小值,再利用这个求出第i行第j列到第i+n-1行第j+n-1列的最大最小值。最后枚举一下求最小的差就行了。反思:本蒟蒻单调队列开始各种符号写反,比如判断是否要l++的那个条件。以及因为INF设得太小WA了一发,拍都拍不出,最后改成2147483647乱交一发结果过了。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define maxn 1500
     5 #define inc(i,j,k) for(int i=j;i<=k;i++)
     6 #define INF 2147483647
     7 using namespace std;
     8 
     9 int maxh[maxn][maxn],minh[maxn][maxn],maxl[maxn][maxn],minl[maxn][maxn];
    10 int v[maxn][maxn],q1[maxn],q2[maxn],a,b,n,l,r,ans;
    11 int main(){
    12     scanf("%d%d%d",&a,&b,&n); inc(i,1,a)inc(j,1,b)scanf("%d",&v[i][j]);
    13     inc(i,1,a){
    14         l=1; r=0;
    15         inc(j,1,n){while(r>=l&&v[i][j]>q1[r])r--; q1[++r]=v[i][j]; q2[r]=j;} maxh[i][1]=q1[l];
    16         inc(j,n+1,b){
    17             if(j-n>=q2[l])l++; while(r>=l&&v[i][j]>q1[r])r--;
    18             q1[++r]=v[i][j]; q2[r]=j; maxh[i][j-n+1]=q1[l];
    19         }
    20     }
    21     inc(i,1,a){
    22         l=1; r=0;
    23         inc(j,1,n){while(r>=l&&v[i][j]<q1[r])r--; q1[++r]=v[i][j]; q2[r]=j;} minh[i][1]=q1[l];
    24         inc(j,n+1,b){
    25             if(j-n>=q2[l])l++; while(r>=l&&v[i][j]<q1[r])r--;
    26             q1[++r]=v[i][j]; q2[r]=j; minh[i][j-n+1]=q1[l];
    27         }
    28     }
    29     inc(j,1,b){
    30         l=1; r=0;
    31         inc(i,1,n){while(r>=l&&maxh[i][j]>q1[r])r--; q1[++r]=maxh[i][j]; q2[r]=i;} maxl[1][j]=q1[l];
    32         inc(i,n+1,a){
    33             if(i-n>=q2[l])l++; while(r>=l&&maxh[i][j]>q1[r])r--;
    34             q1[++r]=maxh[i][j]; q2[r]=i; maxl[i-n+1][j]=q1[l];
    35         }
    36     }
    37     inc(j,1,b){
    38         l=1; r=0;
    39         inc(i,1,n){while(r>=l&&minh[i][j]<q1[r])r--; q1[++r]=minh[i][j]; q2[r]=i;} minl[1][j]=q1[l];
    40         inc(i,n+1,a){
    41             if(i-n>=q2[l])l++; while(r>=l&&minh[i][j]<q1[r])r--;
    42             q1[++r]=minh[i][j]; q2[r]=i; minl[i-n+1][j]=q1[l];
    43         }
    44     }
    45     ans=INF;
    46     inc(i,1,a-n+1)inc(j,1,b-n+1){
    47         ans=min(ans,maxl[i][j]-minl[i][j]);
    48     }
    49     printf("%d",ans); return 0;
    50 }

    20160527

  • 相关阅读:
    C语言-第四周作业
    第8次Scrum会议(10/20)【欢迎来怼】
    例行报告(20171011-20171019)
    C语言--第二周作业评分和总结(5班)
    C语言-第三周作业
    第一次Scrum会议(10/13)【欢迎来怼】
    单元测试之四则运算
    四则运算V1.1
    例行报告(20170927-20171010)
    C语言--第一周作业评分和总结(5班)
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5698476.html
Copyright © 2020-2023  润新知