[Daimayuan] 三段式(C++,数组前缀和)

这篇具有很好参考价值的文章主要介绍了[Daimayuan] 三段式(C++,数组前缀和)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

有一个长度为 n n n的序列,现在我们想把它切割成三段(每一段都是连续的),使得每一段的元素总和都相同,请问有多少种不同的切割方法

输入描述

第一行给出一个数 n n n,( 1 ≤ n ≤ 1 0 5 1≤n≤10^5 1n105)

第二行给出序列 a 1 a_1 a1 a 2 a_2 a2 a 3 a_3 a3,…, a n a_n an,( ∣ a i ∣ ≤ 1 0 5 |a_i|≤10^5 ai105)

输出描述

输出一个数表示有多少种不同的切割方法

样例输入
4
1 2 3 3
样例输出
1
样例解释

可以将它分成第一组 1 1 1 2 2 2,第二组 3 3 3,第三组 3 3 3

解题思路

根据题意,很容易得到下面的公式:
s u m 1 + s u m 2 + s u m 3 = s u m s u m 1 = s u m 2 = s u m 3 s u m 1 = s u m 2 = s u m 3 = 1 3 s u m sum_1+sum_2+sum_3=sum\\ sum_1=sum_2=sum_3\\ \\ sum_1=sum_2=sum_3=\frac{1}{3}sum sum1+sum2+sum3=sumsum1=sum2=sum3sum1=sum2=sum3=31sum
要满足题意有两个前提条件(特殊判定):

(1) s u m   %   3 = = 0 sum\ \%\ 3==0 sum % 3==0

(2) n ≥ 3 n\ge3 n3

if (n < 3 || sum % 3 != 0) {
    cout << 0 << endl;
    return 0;
}

然后我们来寻找可能的分割方式。

如果有多于 1 1 1种的分割方法,那么一定存在子段和为 0 0 0

与其去找子段和为 0 0 0的部分,不如转化思维,使用前缀和的概念(经常用于连续区间和问题)。

这样我们就只需要寻找前缀和同为 1 3 s u m \frac13sum 31sum的部分了。

然后具体问题具体分析,因为题目中只要求分割为三段,所以我们直接找出前后两段 1 3 s u m \frac13sum 31sum即可。

注意,至少要为中间的 1 3 s u m \frac13sum 31sum预留一个元素的位置。

long long ans = 0;
for (int i = 1; i <= n - 1; i++) {
	if (pre[i] == subsum) {
		ans += tail_counter[i + 2];
	}
}

其中tail_counter中的元素意义为: i i i位置及其之后有多少个后缀和为 1 3 s u m \frac13sum 31sum

最后,AC代码如下:文章来源地址https://www.toymoban.com/news/detail-452101.html

#include <iostream>
using namespace std;
const int max_n = 1e5;

long long arr[max_n + 1], pre[max_n + 1], tail[max_n + 2];
long long tail_counter[max_n + 1];

int main() {
	int n;
	long long sum = 0;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> arr[i];
		sum += arr[i];
	}

	if (n < 3 || sum % 3 != 0) {
		cout << 0 << endl;
		return 0;
	}
	long long subsum = sum / 3;
	for (int i = 1; i <= n; i++) {
		pre[i] = arr[i] + pre[i - 1];
	}
	for (int i = n; i >= 1; i--) {
		tail[i] = arr[i] + tail[i + 1];
		tail_counter[i] = tail_counter[i + 1];
		if (tail[i] == subsum) tail_counter[i]++;
	}
	long long ans = 0;
	for (int i = 1; i <= n - 1; i++) {
		if (pre[i] == subsum) {
			ans += tail_counter[i + 2];
		}
	}
	cout << ans << endl;
	return 0;
}

到了这里,关于[Daimayuan] 三段式(C++,数组前缀和)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Verilog基础:三段式状态机与输出寄存

    相关阅读 Verilog基础 https://blog.csdn.net/weixin_45791458/category_12263729.html         对于Verilog HDL而言,有限状态机(FSM)是一种重要而强大的模块,常见的有限状态机书写方式可以分为一段式,二段式和三段式,笔者强烈建议使用三段式因为这样能使状态机逻辑清晰且易于维护。    

    2024年02月04日
    浏览(41)
  • 三段式电流保护与自动重合闸MATLAB仿真模型

    微 ❤ 关注“电气仔推送”获得资料(专享优惠) 前加速、后加速的区别: 前加速是保护装置不判别是永久性故障还是瞬时故障,直接跳闸,然后经重合闸装置来纠正;后加速是保护装置是先判别故障类型有选择性跳闸 以下只叙述后加速的相关内容,前加速不在赘述!!!

    2024年02月02日
    浏览(36)
  • 【附源码】基于fpga的自动售货机(三段式状态机)

    目录 1、VL38 自动贩售机1 题目介绍 思路分析 代码实现 仿真文件 2、VL39 自动贩售机2 题目介绍: 题目分析 代码实现 仿真文件 3、状态机基本知识         设计一个自动贩售机,输入货币有三种,为0.5/1/2元,饮料价格是1.5元,要求进行找零,找零只会支付0.5元。 ps:   

    2024年02月01日
    浏览(39)
  • Verilog写状态机的三种描述方式之三段式

    状态机的设计思路: 一是从状态机变量入手,分析各个状态的输入、状态转移和输出; 二是先确定电路的输出关系,再回溯规划每个状态的条件、输入等; 状态机的三要素是状态、输入和输出 , 根据状态机状态是否和输入条件相关,可以分为Moore型状态机(与输入无关)和

    2024年02月14日
    浏览(42)
  • 【零基础玩转BLDC系列】无刷直流电机无位置传感器三段式启动法详细介绍及代码分享

    无刷直流电动机基本转动原理等内容请参考《基于霍尔传感器的无刷直流电机控制原理》、《基于反电动势过零检测法的无刷直流电机控制原理》与《以GD32F30x为例定时器相关功能详解》,BLDC基本原理及基础知识本篇不再赘述。 直流无刷电机由于定子绕组的反电动势与电机的

    2023年04月08日
    浏览(84)
  • 【力扣】1588. 所有奇数长度子数组的和 <前缀和>

    给你一个正整数数组 arr ,请你计算所有可能的奇数长度子数组的和。子数组 定义为原数组中的一个连续子序列。请你返回 arr 中 所有奇数长度子数组的和 。 示例 1: 输入:arr = [1,4,2,5,3] 输出:58 解释:所有奇数长度子数组和它们的和为: [1] = 1 [4] = 4 [2] = 2 [5] = 5 [3] = 3 [1

    2024年02月10日
    浏览(38)
  • 前缀和+单调双队列+贪心:LeetCode2945:找到最大非递减数组的长度

    C++算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 单调双队列 贪心 给你一个下标从 0 开始的整数数组 nums 。 你可以执行任意次操作。每次操作中,你需要选择一个 子数组 ,并将这个子数组用它所包含元素的 和 替换。比方说,给定数组是 [1,3,

    2024年02月03日
    浏览(29)
  • 【面试经典 150 | 数组】最后一个单词的长度

    本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更…… 专栏内容以分析题目为主,并附带一些对于本题涉及到的数据结构等内容进行回顾与总结,文章结构大致如下,部分内容会有增删: Tag:介绍本题牵涉到的知识点、数据结构; 题目来源:

    2024年04月22日
    浏览(58)
  • C++中变量作为数组长度

    在 C + + C++ C + + 中无法使用变量作为数组长度,必须使用常量 因为数组空间分配在栈内存中,这部分空间大小必须在编译时就确定,不能等到运行时再分配,而常量值编译时就确定,变量须运行时才能确定 因此,想要使用变量声明数组长度,可以选择将数组空间开辟在堆内存

    2024年02月07日
    浏览(27)
  • C++前缀和算法:生成数组原理、源码及测试用例

    C++算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 动态规划,日后完成。 给定三个整数 n、m 和 k 。考虑使用下图描述的算法找出正整数数组中最大的元素。 请你构建一个具有以下属性的数组 arr : arr 中包含确切的 n 个整数。 1 = arr[i] = m 其中 (

    2024年02月06日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包