首页 > 其他分享 >【代码随想录】一、数组:6.前缀和

【代码随想录】一、数组:6.前缀和

时间:2024-08-15 21:39:41浏览次数:16  
标签:前缀 int sum 随想录 cin ++ vec 数组 include

二刷的时候发现更新了一些新的题目,尝试写了写后,发现我完全不会ACM输入输出模式。
这两天在补前几天没背的八股,写得不够满意(几乎是完全誊代码了),先放着,后面再补充补充吧。

1.题目:44. 开发商购买土地

#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];
        }
    }
    // 统计横向
    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));
    }
    int verticalCut = 0;
    for (int j = 0; j < m; j++) {
        verticalCut += vertical[j];
        result = min(result, abs(sum - verticalCut - verticalCut));
    }
    cout << result << endl;
}

2.题目:58.区间和

1.解法1:暴力解法

超时

#include<iostream>
#include<vector>
using namespace std;
  
int main() {
    int n, a, b;
    cin >> n;
    vector<int>nums(n);
    for (int i = 0; i < n; i++) {
        cin >> nums[i];
    }
    while (cin >> a >> b) {
        int sum = 0;
        for (int i = a; i <= b; i++) {
            sum += nums[i];
        }
        cout << sum << endl;
    }
} 

2.解法2:前缀和

前缀和的思想是重复利用计算过的子数组之和,从而降低区间查询需要累加计算的次数。
前缀和 在涉及计算区间和的问题时非常有用!
例如,我们要统计 vec[i] 这个数组上的区间和。
我们先做累加,即 p[i] 表示 下标 0 到 i 的 vec[i] 累加 之和。
如图:
image
在vec数组上 下标 2 到下标 5 之间的累加和,用p[5] - p[1]即可。
image
p[5] - p[1] 就是 红色部分的区间和。
而 p 数组是我们之前就计算好的累加和,所以后面每次求区间和的之后 我们只需要 O(1) 的操作。
特别注意: 在使用前缀和求解的时候,要特别注意 求解区间。

#include<iostream>
#include<vector>
using namespace std;
 
 
int main() {
    int n, a, b;
    cin >> n;
    vector<int>nums(n);
    vector<int>sum(n);
    int presum = 0;
    for (int i = 0; i < n; i++) {
        cin >> nums[i];
        presum += nums[i];
        sum[i] = presum;
    }
    
    while (cin >> a >> b) {
        int ans;
        if (a == 0) ans = sum[b];
        else ans = sum[b] - sum[a - 1]; 
        cout << ans << endl;
    }
} 

C++ 代码 面对大量数据 读取 输出操作,最好用scanf 和 printf,耗时会小很多:

#include<iostream>
#include<vector>
using namespace std;
 
 
int main() {
    int n, a, b;
    cin >> n;
    vector<int>nums(n);
    vector<int>sum(n);
    int presum = 0;
    for (int i = 0; i < n; i++) {
        scanf("%d", &nums[i]);
        presum += nums[i];
        sum[i] = presum;
    }
    
    while (~scanf("%d%d", &a, &b)) {
        int ans;
        if (a == 0) ans = sum[b];
        else ans = sum[b] - sum[a - 1]; 
        printf("%d\n", ans);
    }
} 

标签:前缀,int,sum,随想录,cin,++,vec,数组,include
From: https://www.cnblogs.com/Henfiu/p/18361839

相关文章

  • 【代码随想录】一、数组:4.滑动窗口
    1.题目1:209.长度最小的子数组1.1.解法1:暴力解法(已超时)使用两层循环,外层循环确定最小子数组开始的位置(i),内层循环确定最小子数组结束的位置(j)。在每次跳出内层循环时,sum应重置为0。当找到的子数组相加的和等于或大于目标值(target)时,算出此刻子数组的长度(j-i+1),并更新result的值......
  • 【代码随想录】一、数组:5.螺旋矩阵
    本题并不涉及到什么算法,就是模拟过程,但却十分考察对代码的掌控能力。1.题目1:59.螺旋矩阵II1.1.解法1:模拟本题的重点还是像之前的“704.二分查找”,坚持循环不变量原则,即在本题中遍历每条边时,坚持相同的原则。如下是一个示例,即n=5,我们考虑根据圈数和边数来进行遍历:由外圈到内......
  • D44 2-SAT+前缀优化+二分 CF587D Duff in Mafia
    视频链接: CF587DDuffinMafia-洛谷|计算机科学教育新生态(luogu.com.cn)#include<iostream>#include<cstring>#include<algorithm>#include<vector>usingnamespacestd;constintN=500005;inthead[N],idx,ne[N*6],to[N*6];voidadd(intx,......
  • KMP算法——理解 next 数组
    !注意!本文与《王道》,《严书》有所不同,字符串均从第0位开始,next数组没有添加常数1。博客为梳理思路所用,难免纰漏,希望不吝赐教。在字符串匹配中,设m为待匹配的主串S长度,n为找寻的模式串T长度。如:在主串S='ababc'中寻找模式串T='abc'则字符串匹配算法返回S中第......
  • 代码随想录算法训练营 | 动态规划 part01
    509.斐波那契数509.斐波那契数状态转移方程:F(0)=0,F(1)=1F(n)=F(n-1)+F(n-2),其中n>1递归,太多重复计算classSolution{public:intfib(intn){if(n==0||n==1){returnn;}returnfib(n-1)......
  • JS 数组的用法
    一、常用的测试写法//array的写法varmyArray=["Apple","Orange","Banana"];//一、正常循环写法如下:varfruitFinal3=""for(vari=0;i<myArray.length;i++){fruitFinal3+=myArray[i]+""......
  • 代码随想录算法训练营第一天 | 704. 二分查找,27. 移除元素
     704.二分查找题目链接:https://leetcode.cn/problems/binary-search/1,左闭右闭publicintsearch(int[]nums,inttarget){intlow=0;inthigh=nums.length-1;while(low<=high){intmid=(high+low)/2;if(num......
  • JavaScript实现数组与树结构的相互转换
    1、将树结构数据转换为数组(按照树结构自上而下的顺序转换)树结构:树结构数据样例:代码转换://将树结构数据转换为数组treeNodes为树结构形式的数据functiontreeToArray(treeNodes){letresult=[];//递归函数traverse,用于处理单个节点functiontraverse(node......
  • 代码随想录算法训练营第43天:动态规划part10:子序列问题
    300.最长递增子序列力扣题目链接(opensnewwindow)给你一个整数数组nums,找到其中最长严格递增子序列的长度。子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7]是数组[0,3,1,6,2,2,7]的子序列。示例1:输入:nums=[10,9,2......