【单调队列】COGS 308. [HAOI2007] 理想的正方形
2013-10-22 17:39
218 查看
orz大神,附上链接:http://blog.csdn.net/orpinex/article/details/7179078
题目链接:http://cojs.tk/cogs/problem/problem.php?pid=308
分析:
对每一列用单调队列维护从这个点开始接下来n个数里面最大的和最小的
那么对于一列上的n个数,我们把它压成了一个数
lmax[i][j],lmin[i][j]分别表示以这个点为起点往下n个数里面最大和最小
那么我们对这个两个数组横向的也用单调队列维护
那么对于每一行,我们又把它压成了一个数
hmax[i][j],hmin[i][j]就表示这个点为左上角的正方形里面最大和最小的了
然后暴力O(ab)的找答案就可以了
代码:
题目链接:http://cojs.tk/cogs/problem/problem.php?pid=308
分析:
对每一列用单调队列维护从这个点开始接下来n个数里面最大的和最小的
那么对于一列上的n个数,我们把它压成了一个数
lmax[i][j],lmin[i][j]分别表示以这个点为起点往下n个数里面最大和最小
那么我们对这个两个数组横向的也用单调队列维护
那么对于每一行,我们又把它压成了一个数
hmax[i][j],hmin[i][j]就表示这个点为左上角的正方形里面最大和最小的了
然后暴力O(ab)的找答案就可以了
代码:
#include<cstdio> #include<iostream> #include<queue> using namespace std; int lmax[1008][1008],lmin[1008][1008], hmax[1008][1008],hmin[1008][1008], n,m,r,c,map[1008][1008],ans=2000000000; typedef pair<int,int> pii; deque<pii> qmax,qmin; void calc(int col) { qmax.clear();qmin.clear(); for (int i=1;i<=r;i++) { while (!qmax.empty()&&i-qmax.front().second>=n) qmax.pop_front(); while (!qmin.empty()&&i-qmin.front().second>=n) qmin.pop_front(); while (!qmax.empty()&&qmax.back().first<=map[i][col]) qmax.pop_back(); while (!qmin.empty()&&qmin.back().first>=map[i][col]) qmin.pop_back(); qmax.push_back(pii(map[i][col],i)); qmin.push_back(pii(map[i][col],i)); if (i>=n) lmax[i-n+1][col]=qmax.front().first, lmin[i-n+1][col]=qmin.front().first; } } void calc2(int col) { qmax.clear();qmin.clear(); for (int i=1;i<=c;i++) { while (!qmax.empty()&&i-qmax.front().second>=n) qmax.pop_front(); while (!qmin.empty()&&i-qmin.front().second>=n) qmin.pop_front(); while (!qmax.empty()&&qmax.back().first<=lmax[col][i]) qmax.pop_back(); while (!qmin.empty()&&qmin.back().first>=lmin[col][i]) qmin.pop_back(); qmax.push_back(pii(lmax[col][i],i)); qmin.push_back(pii(lmin[col][i],i)); if (i>=n) hmax[col][i-n+1]=qmax.front().first, hmin[col][i-n+1]=qmin.front().first; } } int main() { freopen("square.in","r",stdin); freopen("square.out","w",stdout); cin>>r>>c>>n; for(int i=1;i<=r;i++) for (int j=1;j<=c;j++)cin>>map[i][j]; for (int i=1;i<=c;i++) calc(i); for (int j=1;j<=r;j++) calc2(j); for (int i=1;i<=r-n+1;i++) for (int j=1;j<=c-n+1;j++) ans=min(ans,hmax[i][j]-hmin[i][j]); cout<<ans<<endl; return 0; }
相关文章推荐
- [luoguP2216] [HAOI2007]理想的正方形(二维单调队列)
- [BZOJ 1047][HAOI 2007]理想的正方形(二维滑动窗口+单调队列)
- bzoj1047: [HAOI2007]理想的正方形(单调队列)
- [BZOJ1047]HAOI2007理想的正方形|单调队列|DP
- bzoj 1047: [HAOI2007]理想的正方形 (单调队列)
- bzoj 1047: [HAOI2007]理想的正方形【单调队列】
- [HAOI2007]理想正方形-单调队列学习笔记
- BZOJ 1047 HAOI2007 理想的正方形 单调队列
- 【bzoj1047】【单调队列】【HAOI2007】理想的正方形
- 【单调队列】bzoj 1407 [HAOI2007]理想的正方形
- BZOJ1047: [HAOI2007]理想的正方形 单调队列
- [BZOJ 1047] [HAOI2007] 理想的正方形 【单调队列】
- [bzoj1047][HAOI2007]理想的正方形【单调队列】
- bzoj 1047 : [HAOI2007]理想的正方形 单调队列dp
- 【单调队列】bzoj1047 [HAOI2007]理想的正方形
- bzoj1047[HAOI2007]理想的正方形 单调队列
- [bzoj 1047][HAOI2007]理想正方形(单调队列)
- [bzoj1047][HAOI2007]理想的正方形(单调队列)
- BZOJ1047: [HAOI2007]理想的正方形 [单调队列]
- [bzoj1047][HAOI2007]理想的正方形_动态规划_单调队列