学习概要
代码随想录
数组
7.区间和:Kamacoder58
要点:前缀和,暴力解法时间复杂度高,有冗余运算.所以采用前缀和的思想来解决区间计算问题。
前缀和的思想是重复利用计算过的子数组之和,从而降低区间查询需要累加计算的次数。
前缀和 在涉及计算区间和的问题时非常有用!
前缀和的思路其实很简单,我给大家举个例子很容易就懂了。
例如,我们要统计 vec[i] 这个数组上的区间和。
我们先做累加,即 p[i] 表示 下标 0 到 i 的 vec[i] 累加 之和。
如果,我们想统计,在vec数组上 下标 2 到下标 5 之间的累加和,那是不是就用 p[5] - p[1] 就可以了。
为什么呢?
p[1] = vec[0] + vec[1];
p[5] = vec[0] + vec[1] + vec[2] + vec[3] + vec[4] + vec[5];
p[5] - p[1] = vec[2] + vec[3] + vec[4] + vec[5];
以下为暴力解法代码以及AC代码
/*#include<iostream>
#include<vector>
using namespace std;
int main () {
int n;
cin >> n;
vector<int> arr(n);//(n)可以的
for(int i=0;i<n;i++)
{
cin >> arr[i];
}
int a,b,sum=0;
for(int i=0;;i++)
{
sum=0;
cin >> a >> b;
if(cin.fail()){break;}
for(int j=a;j<=b;j++)
{
sum+=arr[j];
}
//while(cin >> a >> b){
// for(int j=a;j<=b;j++)
// {
// sum+=arr[j];
// }
//}
cout << sum << endl;
}
}
*/
#include<iostream>
#include<vector>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> arr(n);
vector<int> sum(n,0);
for(int i=0;i<n;i++)
{
cin >> arr[i];
if(i==0){sum[i]=arr[i];}
else{sum[i]=sum[i-1]+arr[i];}
}
int a,b;
while(cin >> a >> b)
{
if(a==0){cout << sum[b] << endl;}
else{cout << sum[b]-sum[a-1] << endl;}
}
}
8.开发商购买土地kamacoder44
要点:暴力接法的话使用一个for枚举分割线,里面嵌套连个for计算和,时间复杂度过于高了。所以想到分行列。在用列划分的时候,将每一列的和组成一个新的一维数组。在用行划分的时候,将每一行的和组成一个新的以为数组。这样分别求差距最小。说明:在一个一维数组求和的话可以灵活使用前缀和,本题使用不使用都ok
以下附上AC代码
注释掉的部分也是正确的,但是稍显冗余,且空间复杂度高
#include<iostream>
#include<vector>
#include<math.h>
using namespace std;
int main() {
int n,m;
cin >> n >> m ;
int sum=0;
int min;//
int sum_a=0,sum_b=0;
vector<vector<int>> x(n,vector<int>(m,0));
//vector<vector<int>> matrix_initialized(3, vector<int>(4, 0));
vector<int> sum_x(n,0);
vector<int> sum_x_sum(n,0);
vector<int> sum_y(m,0);
vector<int> sum_y_sum(m,0);
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cin >> x[i][j];
sum_y[j]+=x[i][j];
sum_x[i]+=x[i][j];
sum+=x[i][j];
}
}
min=sum;
/*for(int i=0;i<n;i++)
{
if(i==0){sum_x_sum[i]=sum_x[i];}
else{sum_x_sum[i]=sum_x_sum[i-1]+sum_x[i];}
//cout << sum_x[i] << endl;
}
for(int i=0;i<m;i++)
{
if(i==0){sum_y_sum[i]=sum_y[i];}
else{sum_y_sum[i]=sum_y_sum[i-1]+sum_y[i];}
//cout << sum_y[i] << endl;
}
for(int i=0;i<n-1;i++)
{
if(abs(sum_x_sum[i]-(sum-sum_x_sum[i]))<min){
min=abs(sum_x_sum[i]-(sum-sum_x_sum[i]));
}
}
for(int i=0;i<m-1;i++)
{
if(abs(sum_y_sum[i]-(sum-sum_y_sum[i]))<min){
min=abs(sum_y_sum[i]-(sum-sum_y_sum[i]));
}
}*/
for(int i=0;i<n-i;i++)
{
sum_a+=sum_x[i];
if(abs(sum_a-(sum-sum_a))<min){
min=abs(sum_a-(sum-sum_a));
}
}
for(int i=0;i<m-i;i++)
{
sum_b+=sum_y[i];
if(abs(sum_b-(sum-sum_b))<min){
min=abs(sum_b-(sum-sum_b));
}
}
cout << min << endl;
}