zoukankan      html  css  js  c++  java
  • HAOI2007 理想的正方形 单调队列

    单调队列

    by   GeneralLiu

    滑动窗口是比较裸的单调队列

    理想的正方形   就拔高了一个层次(多了一维)

    有一个a*b的整数组成的矩阵

    现请你从中找出一个n*n的正方形区域

    使得该区域所有数中的最大值和最小值的差最小

    只写MAX了,MIN一个道理,懒 不写了

    先横着跑单调队列

      维护许多长度为 n 的 横着的MAX

      存在数组 map1[][] 中

    再对数组 map1[][] 竖着跑单调队列

      就维护了 许多 n*n 的 矩阵的MAX

    MIN同理

    在竖着跑单调队列时

    顺便MAX 与 MIN 作差

    更新答案即可

    代码

    一个小地方debug了好久

    代码上还有 

    学 mzx dalao  “ 二分出错位置  输出中间答案 ” 的 “ 蛛丝马迹 ”

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define A 1005
      4 #define N 105
      5 int an=1000000001,h2,t2,h1,t1,a,b,n;
      6 int pos1[A],pos2[A],que1[A],que2[A];
      7 int mip1[A][A],map1[A][A];
      8 int mip2[A][A],map2[A][A];
      9 int read(){  //  读入优化 
     10     int ans=0;
     11     char ch=getchar();
     12     for(;!isdigit(ch);ch=getchar());
     13     for(;isdigit(ch);ch=getchar())
     14         ans=ans*10+ch-'0';
     15     return ans;
     16 }
     17 int main(){
     18     a=read(),b=read(),n=read();
     19     for(int k,i=1;i<=a;i++){
     20         h1=h2=1;
     21         t1=t2=0;
     22         for(int j=1;j<=b;j++){
     23             k=read();
     24             
     25             for(;t1>=h1&&k>=que1[t1];t1--);
     26             que1[++t1]=k;
     27             pos1[t1]=j;
     28             
     29             for(;t2>=h2&&k<=que2[t2];t2--);
     30             que2[++t2]=k;
     31             pos2[t2]=j;
     32             
     33             if(j>=n){
     34                 map1[i][j]=que1[h1];
     35                 mip1[i][j]=que2[h2];
     36                 if(pos1[h1]==j-n+1)h1++;
     37                 if(pos2[h2]==j-n+1)h2++;
     38             }
     39         }
     40     }
     41     /*cout<<endl;
     42     for(int i=1;i<=a;i++){
     43       for(int j=1;j<=b;j++)
     44         cout<<map1[i][j]<<" ";
     45       cout<<endl;
     46     }
     47     cout<<endl;
     48     for(int i=1;i<=a;i++){
     49       for(int j=1;j<=b;j++)
     50         cout<<mip1[i][j]<<" ";
     51       cout<<endl;
     52     }
     53     cout<<endl;*/
     54     for(int k1,k2,i=n;i<=b;i++){
     55         h1=h2=1;
     56         t1=t2=0;
     57         for(int j=1;j<=a;j++){
     58             k1=map1[j][i];
     59             k2=mip1[j][i];
     60             
     61             for(;t1>=h1&&k1>=que1[t1];t1--);
     62             que1[++t1]=k1;
     63             pos1[t1]=j;
     64             
     65             for(;t2>=h2&&k2<=que2[t2];t2--);
     66             que2[++t2]=k2;
     67             pos2[t2]=j;
     68             
     69             
     70             if(j>=n){
     71               //map2[j][i]=que1[h1];
     72               //mip2[j][i]=que2[h2];
     73               an=min(an,que1[h1]-que2[h2]);
     74               if(pos1[h1]==j-n+1)h1++;
     75               if(pos2[h2]==j-n+1)h2++;
     76             }
     77         }
     78     }
     79     
     80     /*for(int i=1;i<=a;i++){
     81       for(int j=1;j<=b;j++)
     82         cout<<map2[i][j]<<" ";
     83       cout<<endl;
     84     }
     85     cout<<endl;
     86     for(int i=1;i<=a;i++){
     87       for(int j=1;j<=b;j++)
     88         cout<<mip2[i][j]<<" ";
     89       cout<<endl;
     90     }
     91     cout<<endl;*/
     92     
     93     cout<<an;
     94     
     95     return 0;
     96 }/*5 4 2 
     97 1 2 5 6 
     98 0 17 16 0 
     99 16 17 0 1 
    100 2 10 2 1 
    101 1 2 3 2
    102 
    103 2
    104 */
  • 相关阅读:
    按列数自动换行
    百度C 语言吧 · 问题资料大全
    最新动态.某美女象山旅游计划
    被点名了,玩个游戏。
    我们仍未知道那天所看见的题的解法 1
    我们仍未知道那天所看见的题的解法 2
    算法初探 平衡树
    排列组合
    HttpRunner2.X开源接口测试框架学习(一):介绍与安装
    jmeter基础一:JMeter的主要测试组件总结
  • 原文地址:https://www.cnblogs.com/1227xq/p/6794595.html
Copyright © 2011-2022 走看看