采油区域

蓝桥杯上面的题目这题说的是 给了 一个n*m的矩阵 然后取其中的 k*k 大小的面积出来 计算这样取出的三块的最大可以采油的大小最大  将一个矩形区域分成 三块有 6种切法 1上 中下,2 左中右 3 左右下 4 左上下 5 右上下 6 上 左右 然后处理好每个区域所能取到的值 然后 枚举两条线 得到 三个区域 计算最大值 在上中下 左中右 的情况是枚举中间区域是K宽度的 地方  调试了好久

#include <cstdio>
#include <string.h>
#include <iostream>
using namespace std;
const int maxn = 1505;
struct oil{
    int up_Right[maxn][maxn],up_Left[maxn][maxn],down_Right[maxn][maxn],down_Left[maxn][maxn];
    int map[maxn][maxn],row[maxn][maxn],column[maxn][maxn],N,M,K;
    int valu_column[maxn],valu_row[maxn],ans;
    int maxv(int a,int b){    
        return a>b?a:b;
    }
    void read(){
        scanf("%d%d%d",&N,&M,&K); 
        memset(row,0,sizeof(row));
        memset(column,0,sizeof(column));
        memset(up_Left,0,sizeof(up_Left));
        memset(up_Right,0,sizeof(up_Right));
        memset(down_Right,0,sizeof(down_Right));
        memset(down_Left,0,sizeof(down_Left));
        memset(valu_row,0,sizeof(valu_row));
        memset(valu_column,0,sizeof(valu_column));
        for( int i = 1 ; i <= N ; ++ i )
            for( int j =  1 ;j <= M ; ++ j )
               scanf("%d",&map[i][j]);
        for( int i = 1; i <= N ;i++ )        
                for( int j=1; j <= M ; ++ j){
                 row[i][j] = row[i][j-1] + map[i][j];
              column[i][j] = column[i-1][j] + map[i][j] ;
         }    
    }
    void prepare(){
          
    for(int i = K ; i <= N ; ++ i){
          int sum = 0;
          for( int j =  1; j <=K ; j++ )
          sum+=column[i][j]-column[i-K][j];
          up_Left[i][K]=maxv(sum,up_Left[i-1][K]);
          valu_row[i] = sum;
        for( int j = K+1 ; j <= M ; j ++ ){       
             sum=sum-(column[ i ][ j - K ]-column[ i - K ][ j - K ])+column[i][j]-column[i-K][j];
              valu_row[i] = maxv(sum,valu_row[i]);
             up_Left[i][j]=maxv(maxv(sum,up_Left[i][j-1]),up_Left[i-1][j]);
        }
    }    
     for( int i=K ;  i <= N ; ++ i ){
          
           int sum = 0 ;
           for( int j=M ; j>M-K ; -- j )
            sum += column[i][j]-column[i-K][j]; 
          up_Right[i][M-K+1]=maxv(up_Right[i-1][M-K+1],sum);
          for( int j=M-K ; j>0 ; -- j){
             sum = sum - (column[i][j+K]-column[i-K][j+K])+column[i][j]-column[i-K][j];
             up_Right[i][j] = maxv( up_Right[i-1][j],maxv(up_Right[i][j+1],sum));         
          } 
      }
      
      for( int j = K  ; j <= M ; ++ j){
          
           int sum = 0;
            for(int i=N ; i > N - K ; -- i)
             sum += row[i][j]-row[i][j-K];
          down_Left[N-K+1][j]=maxv(down_Left[N-K+1][j-1],sum); 
              valu_column[j]=sum;
            for( int i = N- K ; i>0 ; -- i){
                sum = sum -( row[i+K][j]-row[i+K][j-K])+row[i][j]-row[i][j-K];
              valu_column[j]=maxv(valu_column[j],sum);
              down_Left[i][j] = maxv(down_Left[i+1][j],maxv(sum,down_Left[i][j-1]));        
            }
      }    
      
      for( int j=M-K+1; j > 0 ; -- j ){
         int sum =  0;
         for(int i= N ; i > N - K ; -- i)
          sum += row[i][j+K-1]-row[i][j-1];    
          down_Right[N-K+1][j]=maxv(sum,down_Right[N-K+1][j+1]);    
         for( int i = N-K ; i > 0 ; -- i){
            sum=sum -(row[i+K][j+K-1]-row[i+K][j-1]) + row[i][j+K-1] - row[i][j-1];
            down_Right[i][j]=maxv(down_Right[i+1][j],maxv(sum,down_Right[i][j+1]));    
         }
      }    
          
    }
    void solve(){
        ans =0;
        for( int i=K ; i <= N-K*2; i++ )
        ans = maxv( ans , up_Left[i][M]+valu_row[i+K]+down_Right[i+K+1][1]);
        for( int i = K ;i <= M- K*2 ; i++)
         ans =maxv(ans, up_Left[N][i]+valu_column[i+K]+up_Right[N][i+K+1]);
        for( int i=K; i<=N-K; i++)
         for( int j = K ;j <= M-K ;++ j){
             
             ans=maxv(ans,up_Left[i][j]+up_Right[i][j+1]+down_Left[i+1][M]);
             ans=maxv(ans,up_Left[N][j]+up_Right[i][j+1]+down_Right[i+1][j+1]);
             ans=maxv(ans,up_Left[i][j]+up_Right[N][j+1]+down_Left[i+1][j]);
             ans=maxv(ans,up_Left[i][M]+down_Left[i+1][j]+down_Right[i+1][j+1]);
         }
    
    }
    
}T;
int main(){
      
     T.read();
     T.prepare();      
     T.solve();
     printf("%d
",T.ans);
    return 0;
}
View Code

 

原文地址:https://www.cnblogs.com/Opaser/p/3741415.html