3 条题解

  • 0
    @ 2026-5-17 15:46:44
    #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
      @ 2026-5-12 20:30:46
      #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
        @ 2026-4-27 16:46:13

        思路

        单调队列。

        首先,对于每个点 ai,ja_{i,j},求出这个点往 ss 个点的最大值,存到另一个数组 bb 中,bb 数组有 nnms+1m-s+1 列。

        接着,先枚举列坐标,再从 bb 数组上计算出这个点所在的那一列往 rr 个点的最大值,存到数组 cc 中,cc 数组就是我们的答案数组。

        代码

        #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
        上传者