前缀和是一种思维巧妙很实用 而且 很有容易理解的一种算法思想,大家可以体会一下
文章讲解:58. 区间和 | 代码随想录
题目链接:
58. 区间和(第九期模拟笔试) (kamacoder.com)
思路:先把数组的累加值求出来放在一个新数组里,然后你要求位置2-5的累加值,就是用位置5的累加值减去位置1的累加值
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n,a,b,presum=0;
cin>>n;
vector<int> vec(n);%定义原数组
vector<int> p(n);%定义放着累计值的数组
for(int i=0;i<n;i++){
cin>>vec[i];
presum+=vec[i];
p[i]=presum;
}
while(cin >> a >> b){%输入取值区间
int sum;
if(a==0) sum=p[b];
else sum=p[b]-p[a-1];
cout << sum << endl;
}
}
错误原因:vector定义的时候用()决定类的元素个数vector<int>a(3),但是你在索引的时候必须还是用[]表示,比如a[1];
连续输入两个值分别赋给a和b用的是cin>>a>>b;
开发商购买土地
题目链接
44. 开发商购买土地(第五期模拟笔试) (kamacoder.com)
思路:先输入n行m列,然后输入矩阵的元素,然后求所有矩阵元素的总和。接着就是创建数组求前面每一行元素的总和,创建数组求每一列的总和。然后就是去遍历不同的划分方法算前面n行或者前面n列的元素和与剩下部分元素和的最小差值。
代码:
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
int main () {
int n,m;
cin>>n>>m;
int sum=0;
vector<vector<int>> vec(n,vector<int>(m,0));
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>vec[i][j];
sum+=vec[i][j];
}
}%输入n行m列,且输入矩阵的元素,然后求所有元素总和
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(int i=0;i<n;i++){
horizontalcut=horizontal[i];
result=min(result,abs(sum-horizontalcut-horizontalcut));%sum-horizontalcut表示剩下部分的元素和,horizontalcut表示前面n行的元素和,所以两者相减求绝对值。
}%算不同的行分割法对应的差值最小值
int verticalcut=0;
for(int j=0;j<m;j++){
verticalcut=vertical[j];
result=min(result,abs(sum-verticalcut-verticalcut));
}%算不同的列分割法对应的差值最小值
cout<<result<<endl;
}
错误原因:
1.二维vector的定义出错, 正确是 vector<vector<int>> vec(n,vector<int>(m,0));而我写成了vector<vector<int>> vec(n,vector<int> vec(m,0));也就是二维数组的列元素里的数组多写了一个vec;
2.不同分割方法的差值的时候,应该是i<n和j<m,而我用的是i<n-1和j<m-1;但是我发现两个都是对的,输出结果一样的。我选着用n-1和m-1的原因是你不能把前面所有行或者列都分给一个人吧。
3.horizontalcut和verticalcut放的是前n项的和,所以应该是horizontalcut+=horizontal[i]不是=;这里是因为我理解错了前面部分代码功能,把统计了每一行和每一列的元素和放在新数组里,而不是把前面n行和n列的元素和放在新数组里。
4.cout写成了count;