标签:names ace 最小 矩阵 clu 单调队列 大整数 using \n
题面描述
输入格式
输出格式
题解
利用悬线法思想,先对单行处理,再对列处理。
对单行处理时,用滑动窗口思想,单调队列维护即可。
列处理同理。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=1e3+5;
int n,m,len;
int qmx[MAXN],mxl,mxr;
int qmn[MAXN],mnl,mnr;
int a[MAXN][MAXN];
int lmn[MAXN][MAXN],lmx[MAXN][MAXN];
int ans=1e9;
int main(){
scanf("%d%d%d",&n,&m,&len);
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++){
mxl=mxr=mnl=mnr=0;
for (int j=1;j<=m;j++){
while (mxr>mxl&&a[i][qmx[mxr-1]]<a[i][j]) mxr--;
qmx[mxr++]=j;
while (j-qmx[mxl]>=len) mxl++;
while (mnr>mnl&&a[i][qmn[mnr-1]]>a[i][j]) mnr--;
qmn[mnr++]=j;
while (j-qmn[mnl]>=len) mnl++;
lmx[i][j]=a[i][qmx[mxl]]; lmn[i][j]=a[i][qmn[mnl]];
}
}
// for (int i=1;i<=n;i++){
// for (int j=1;j<=m;j++) printf("(%d %d) ",lmn[i][j],lmx[i][j]);
// printf("\n");
// }
for (int i=len;i<=m;i++){
mxl=mxr=mnl=mnr=0;
for (int j=1;j<=n;j++){
while (mxr>mxl&&lmx[qmx[mxr-1]][i]<lmx[j][i]) mxr--;
qmx[mxr++]=j;
while (j-qmx[mxl]>=len) mxl++;
while (mnr>mnl&&lmn[qmn[mnr-1]][i]>lmn[j][i]) mnr--;
qmn[mnr++]=j;
while (j-qmn[mnl]>=len) mnl++;
if (j>=len) ans=min(ans,lmx[qmx[mxl]][i]-lmn[qmn[mnl]][i]);
}
}
printf("%d\n",ans);
return 0;
}
$bzoj1047-HAOI2007$ 理想正方形 $dp$
标签:names ace 最小 矩阵 clu 单调队列 大整数 using \n
原文地址:https://www.cnblogs.com/shjrd-dlb/p/10801055.html