3 条题解
-
0
#include<bits/stdc++.h> using namespace std; typedef long long ll; int n,m,x,y,a[4010][4010],b[4010][4010],l,r; struct N{ int v,x; }q[4010]; int main(){ ios::sync_with_stdio(0); cin.tie(0); cin>>n>>m; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ cin>>a[i][j]; } } cin>>x>>y; for(int j=1;j<=m;j++){ l=1,r=0; for(int i=1;i<=n;i++){ while(l<=r&&i-q[l].x+1>x)l++; while(l<=r&&q[r].v<a[i][j])r--; q[++r]={a[i][j],i}; if(i>=x){ b[i-x+1][j]=q[l].v; } } } n=n-x+1; for(int i=1;i<=n;i++){ l=1,r=0; for(int j=1;j<=m;j++){ while(l<=r&&j-q[l].x+1>y)l++; while(l<=r&&q[r].v<b[i][j])r--; q[++r]={b[i][j],j}; if(j>=y){ cout<<q[l].v<<" ";; } } cout<<'\n'; } return 0; } -
0
#include<bits/stdc++.h> using namespace std; struct PII{int fi,se;}; const int N=4010; int a[N][N],b[N][N],c[N][N]; signed main() { int n,m;cin>>n>>m; for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)cin>>a[i][j]; int h,w;cin>>h>>w; for(int i=1;i<=n;i++) { deque<PII>q; for(int j=1;j<w;j++) { while(!q.empty()&&q.back().fi<=a[i][j])q.pop_back(); q.push_back({a[i][j],j}); } for(int j=w;j<=m;j++) { while(!q.empty()&&q.front().se<j-w+1)q.pop_front(); while(!q.empty()&&q.back().fi<=a[i][j])q.pop_back(); q.push_back({a[i][j],j}); b[i][j-w+1]=q.front().fi; } } for(int i=1;i+w-1<=m;i++) { deque<PII>q; for(int j=1;j<h;j++) { while(!q.empty()&&q.back().fi<=b[j][i])q.pop_back(); q.push_back({b[j][i],j}); } for(int j=h;j<=n;j++) { while(!q.empty()&&q.front().se<j-h+1)q.pop_front(); while(!q.empty()&&q.back().fi<=b[j][i])q.pop_back(); q.push_back({b[j][i],j}); c[j-h+1][i]=q.front().fi; } } for(int i=1;i+h-1<=n;i++){for(int j=1;j+w-1<=m;j++)cout<<c[i][j]<<' ';cout<<'\n';} return 0; } -
0
思路
单调队列。
首先,对于每个点 ,求出这个点往后 个点的最大值,存到另一个数组 中, 数组有 行 列。
接着,先枚举列坐标,再从 数组上计算出这个点所在的那一列往后 个点的最大值,存到数组 中, 数组就是我们的答案数组。
代码
#include<bits/stdc++.h> using namespace std; int n,m,a[4005][4005],ans[4005][4005],r,s,b[4005][4005]; int main(){ //输入 cin>>n>>m; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ cin>>a[i][j]; } } cin>>r>>s; //第一遍单调队列 for(int i=1;i<=n;i++){ deque<int>q; for(int j=1;j<=m;j++){ while(!q.empty()&&a[i][q.back()]<=a[i][j]){ q.pop_back(); } q.push_back(j); while(!q.empty()&&q.front()<=j-s){ q.pop_front(); } if(j>=s) b[i][j-s+1]=a[i][q.front()]; } } //第二遍 for(int j=1;j<=m-s+1;j++){//反着枚举行和列 deque<int>q; for(int i=1;i<=n;i++){ while(!q.empty()&&b[q.back()][j]<=b[i][j]){ q.pop_back(); } q.push_back(i); while(!q.empty()&&q.front()<=i-r){ q.pop_front(); } if(i>=r) ans[i-r+1][j]=b[q.front()][j]; } } //输出,n-r+1行,m-s+1列 for(int i=1;i<=n-r+1;i++){ for(int j=1;j<=m-s+1;j++){ cout<<ans[i][j]<<' '; } cout<<endl; } return 0; }
- 1
信息
- ID
- 7304
- 时间
- 4000ms
- 内存
- 512MiB
- 难度
- 7
- 标签
- 递交数
- 75
- 已通过
- 16
- 上传者