bzoj1047(单调队列,矩阵中)

来源:互联网 发布:网络主播名字大全女 编辑:程序博客网 时间:2024/06/06 02:10

没那么难,不需要什么二维单调队列,其实只要改变一下顺序就好

为了思路清晰,这里采用的结构体+结构体函数写的单调队列


刚开始感觉不会,看hzwer的blog,上面说,题解都太麻烦,还不如手推,就没继续看下去,事实证明这道题回来一看就秒了,也不知道是怎么想的。。。猜的?

其实就是一行一个单调队列,端点每往右移一位,就计算从上到下的情况

#include<cstring>#include<cstdio>#include<cmath>#include<algorithm>using namespace std;const int inf=0x3f3f3f3f;int read(){int ans,f=1;char ch;while ((ch=getchar())<'0'||ch>'9') if (ch=='-') f=-1;ans=ch-'0';while ((ch=getchar())>='0'&&ch<='9') ans=ans*10+ch-'0';return ans*f;}struct aa{int q[1005],id[1005],head,tail;aa (){head=1;tail=0;}void clear(){memset(q,0,sizeof(q));memset(id,0,sizeof(id));head=1;tail=0;}void mx_insert(int x,int idx){while (q[tail]<=x && tail>=head) tail--;//pay attention,注意单调队列边界的情况即可q[++tail]=x;id[tail]=idx;}void mi_insert(int x,int idx){while (q[tail]>=x && tail>=head) tail--;q[++tail]=x;id[tail]=idx;}void del(int k){while (id[head]<=k&&head<=tail) head++;}}mx[1005],mi[1005],smi,smx;//单调队列 int a,b,n,mp[1005][1005],ans;int main(){a=read();b=read();n=read();for (int i=1;i<=a;i++)for (int j=1;j<=b;j++) mp[i][j]=read();ans=inf;for (int i=1;i<=a;i++)for (int j=1;j<=n;j++) mx[i].mx_insert(mp[i][j],j),mi[i].mi_insert(mp[i][j],j);for (int i=1;i<=b-n+1;i++){smx.clear();smi.clear();for (int j=1;j<=n;j++) smx.mx_insert(mx[j].q[mx[j].head],j),smi.mi_insert(mi[j].q[mi[j].head],j);for (int j=1;j<=a-n+1;j++){ans=min(ans,smx.q[smx.head]-smi.q[smi.head]);smx.del(j);smi.del(j);smx.mx_insert(mx[j+n].q[mx[j+n].head],j+n);smi.mi_insert(mi[j+n].q[mi[j+n].head],j+n);}for (int j=1;j<=a;j++){mx[j].del(i);mi[j].del(i);mx[j].mx_insert(mp[j][i+n],i+n);mi[j].mi_insert(mp[j][i+n],i+n);}}printf("%d",ans);return 0;}


0 0
原创粉丝点击