算法day7 开发商购买土地

题目描述

思路:

在这道题中,我们的目标是要求得行列中划分部分的最小差值。我们的思路即在赋值的过程中对整个矩阵求和,这样我们便得到了整体的和。随后,我们可以通过for循环实现求纵向与横向的总和。最后,到了关键的一步,我们之前获得了整体的和sum,随后获得了行和与列和,这是我们可以有“总和 - 部分” + “部分”这样的划分思想,这样就可以获得划分的两部分,随后就是返回二者差值来不断的更新结果,完成。

代码如下

#include <iostream>
#include <climits>
#include <vector>
#include <stdio.h>


using namespace std;

int main(){

int m,n;   
scanf("%d %d",&n,&m);
vector<vector<int>> vec(n,vector<int>(m,0));

int sum = 0; //整个矩阵的总和

for(int i=0;i<n;i++){
    for(int j=0;j<m;j++){
        scanf("%d",&vec[i][j]);
        sum += vec[i][j] ;
    }
}
 
//求每一行的和
vector<int> horizontal(n,0); 
for(int i=0;i<n;i++){
    for(int j=0;j<m;j++){
        horizontal[i] += vec[i][j];
    }
}

//求每一列的和

vector<int> vertical(m,0);
for(int j = 0;j<m;j++){
    for(int i=0;i<n;i++){
        vertical[j] += vec[i][j];
    }
}

int result = INT_MAX;

int horizontalCut = 0;

//接下来的两个for循环在动态划分部分,也可以说是前缀和
for(int i=0;i<n;i++){
    horizontalCut += horizontal[i]; 
    result = min(result,abs(sum-horizontalCut-horizontalCut));
}

int verticalCut = 0;

for(int j=0;j<m;j++){
    verticalCut += vertical[j];
    result = min(result,abs(sum-verticalCut-verticalCut));
}

printf("%d",result);

  return 0;
}

时间复杂度:O(n*m)
空间复杂度:O(n*m)

END

posted on 2025-04-09 21:37  sakura430  阅读(20)  评论(0)    收藏  举报