[HAOI2007]理想的正方形
题目描述
输入
输出
样例输入
样例输出
分析:学习大佬算法,单调队列能这么简单可还行。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <string> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <vector> #include <queue> #include <deque> #include <map> #define range(i,a,b) for(int i=a;i<=b;++i) #define LL long long #define rerange(i,a,b) for(int i=a;i>=b;--i) #define fill(arr,tmp) memset(arr,tmp,sizeof(arr)) using namespace std; int a,b,n,tt[1005][1005],gg[1005][1005],mm[2][1005][1005]; pair<int,int>q[1005]; void init(){ cin>>a>>b>>n; range(i,1,a)range(j,1,b)cin>>tt[i][j]; } void cal(int x){ range(i,1,a){ int left=1,right=0; range(j,1,b){ while(left<=right&&j-q[left].second>=n)++left; if(!x)while(left<=right&&tt[i][j]>=q[right].first)--right; else while(left<=right&&tt[i][j]<=q[right].first)--right; q[++right]=make_pair(tt[i][j],j); gg[i][j]=q[left].first; } } range(j,n,b){ int left=1,right=0; range(i,1,a){ while(left<right&&i-q[left].second>=n)++left; if(!x)while(left<=right&&gg[i][j]>=q[right].first)--right; else while(left<=right&&gg[i][j]<=q[right].first)--right; q[++right]=make_pair(gg[i][j],i); mm[x][i][j]=q[left].first; } } } void solve(){ cal(0);cal(1); int ans=1<<30; range(i,n,a) range(j,n,b)ans=min(ans,mm[0][i][j]-mm[1][i][j]); cout<<ans<<endl; } int main() { init(); solve(); return 0; }