【C/C++】双指针与前缀和

- 第 88 篇 -
Date: 2025 - 04 - 06(发博客时间)
Author: 郑龙浩/仟墨
【双指针与前缀和 C/C++】

双指针与前缀和

记笔记时间: 2025-04-02

文章目录

  • 双指针与前缀和
    • [1 基本介绍](#1 基本介绍)
    • [2 双指针 - 例题](#2 双指针 - 例题)
  • [蓝桥杯第15届C/C++B组省赛 H题 - 拔河](#蓝桥杯第15届C/C++B组省赛 H题 - 拔河)

1 基本介绍

准确来说,双指针只能说是算法中的一个技巧。

它并没有一个固定的模板,只是一个思想

双指针在遍历数据的过程当中不是简单的使用单个指针进行访问(也就是不是遍历一遍),而是使用两个相同方向或者相反方向的指针进行扫描。

双指针也可和前缀和结合使用

两种

  • 最常见

    在一个序列里边, 用两个指针维护一段区间

  • 不常见

    在两个序列里边,一个指针指向其中一个序列,另一个指针指向另一个序列,来维护某种次序。

核心思想

当暴力过不了的时候,可以使用双指针进行优化

2 双指针 - 例题

将两个有序顺序表合并成一个新的有序顺序表,并由函数返回结果顺序表

cpp 复制代码
[38, 49, 65, 97]  [13, 27, 76]

代码

cpp 复制代码
// 将两个有序顺序表合并成一个新的有序顺序表,并由函数返回结果顺序表

// ```cpp
// [38, 49, 65, 97]  [13, 27, 76]
// ```
#include <bits/stdc++.h>
using namespace std;
const int N = 4;
const int M = 3;
int arr[N] = {38, 49, 65, 97}, arr2[M] = {13, 27, 76}, ans[N + M];
int k = 0; // ans的长度
int main( void ) {
    int i = 0, j = 0;
    while (i < N && j < M) {
        if (arr[i] < arr2[j]) ans[k ++] = arr[i ++];
        else ans[k ++] = arr2[j ++];
    }
    // 为什么还要再写两遍while呢
    // 因为会出现两种情况
    // 1 当arr2数组全部放到ans数组中时,arr2数组中的数没完全或者没有放到ans数组中,所以需要二次遍历
    // 2 当arr数组全部放到ans数组中时,arr数组中的数没完全或者没有放到ans数组中,所以需要二次遍历
    
    // i < N  意思是 arr 数组中还有数值没有被遍历
    // j == M 意思是 arr2 数值中的数值已经全部被遍历,因为只有全部被遍历之后才会指向M
    while (i < N && j == M) ans[k ++] = arr[i ++]; //j == m 写不写都行,主要是便于理解的
    while (j < M && i == N) ans[k ++] = arr2[j ++]; //i == N 写不写都行
    for (int i = 0; i < N + M; i ++) {
        cout << ans[i] << ' ';
    }
    return 0;
}

蓝桥杯第15届C/C++B组省赛 H题 - 拔河

cpp 复制代码
// 试题H 洛谷P10429 拔河  第二次写
// Date: 2025-04-04
// Author: 郑龙浩 / 仟墨
// 算法: 双指针 + 前缀和
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e3 + 5;
int n;// 人数
ll arr[N], sumA = 0, sumB = 0, minNum = LLONG_MAX;
int main( void ) {
    cin >> n;
    for (int i = 0; i < n; i ++) cin >> arr[i];
    for (int i = 0; i < n - 1; i ++) {
        for (int j = i + 1; j < n; j ++) {
            sumA = arr[i], sumB = arr[j]; // 重置总和
            minNum = min(minNum, abs(sumB - sumA));
            int l = i - 1, r = j + 1; // 左右
            while (l >= 0 && r < n) { // 若指针指向的是队伍内
                if (sumA < sumB) {
                    sumA += arr[l];
                    l --;
                    minNum = min(minNum, abs(sumB - sumA));
                } else {
                    sumB += arr[r];
                    r ++;
                    minNum = min(minNum, abs(sumB - sumA));
                }
            }
            while (l >= 0 && r == n) {
                sumA += arr[l];
                l --;
                minNum = min(minNum, abs(sumB - sumA));
            }
            while (r < n && l == 0) {
                sumB += arr[r];
                r ++;
                minNum = min(minNum, abs(sumB - sumA));
            }
        }
    }
    cout << minNum << '\n';
    return 0;
}
相关推荐
孤独的追光者11 分钟前
论文阅读|汽车虚拟环绕音响系统设计与实现策略的比较研究
算法·汽车·音频·信号处理·数字信号处理
七七七七0711 分钟前
类与对象【下篇】-- 关于类的其它语法
c语言·开发语言·c++
削好皮的Pineapple!13 分钟前
C语言模块化编程思维以及直流电机控制(第四天)
c语言·开发语言·单片机
黄皮の电气鼠19 分钟前
C++:继承
开发语言·c++·算法
shylyly_20 分钟前
专题一_双指针_查找总价格为目标值的两个商品
c++·算法·leetcode·双指针·查找总价格为目标值的两个商品·和为s的两个数
zzj_26261021 分钟前
高精度乘法
算法
我尽力学23 分钟前
HashMap的get、put流程源码分析
算法·哈希算法
R-G-B1 小时前
【03】MFC入门到精通——MFC 添加控件 设置属性 按钮 文本框
c++·mfc·mfc添加控件
IT猿手1 小时前
2025最新智能优化算法:沙狐优化(Rüppell‘s Fox Optimizer,RFO)算法求解23个经典函数测试集,完整MATLAB代码
android·算法·matlab·迁移学习·优化算法·动态多目标优化·动态多目标进化算法
liulilittle1 小时前
C/C++ inline-hook(x86)高级函数内联钩子
c语言·开发语言·汇编·c++·hook·底层·钩子