首页 > 编程语言 >2.大闹蟠桃园【算法赛】

2.大闹蟠桃园【算法赛】

时间:2024-08-16 10:25:03浏览次数:13  
标签:std 蟠桃 begin end 小路 大闹 算法 序列 分身

哈喽,大家好啊,可爱的宝子们,在讲解正文之前我们不妨来娱乐一下,不知道你们有没有看过最近非常火的一部动漫——《斩神》

今天这部分文章的开头就给大家介绍一下《斩神》中人气非常高的一位神明,她就是古希腊五位创世神之一,又被称为众神之母的黑夜女神——倪克斯.

哈哈,就让我们欣赏一下这位美丽的女神吧!

1.

2.

进入正题!

问题描述:


王母娘娘举办蟠桃会,却未邀请孙悟空。这使得孙悟空怒不可遏他当即决定大闹蟠桃园,要将蟠桃据为己有。


在蟠桃园中,有 N 条小路,编号从1到 N。这些小路构成了一个环形网络,具体来说,小路之与小路i+1(i<n)相互连接小路 N 与小路 1相互连接。每条小路都可能有天兵把守。

为了加快采摘蟠桃的速度,孙悟空施展法术,变出了N 个分身,编号从1到 N。每个分身起初皆立于其对应编号的小路上,且所采摘的蟠桃数量均为 0。每当孙悟空的本体挥动一次金箍棒,所有的分身就都会向右移动到下一条小路,并出现以下情况之一。


如果一个分身走入有天兵把守的小路,它采摘的蟠桃数量将变为 0。如果一个分身走入没有天兵把守的小路,它采摘的的蟠桃数量将增加 1。


孙悟空的本体能够任意次数地挥动金箍棒(包括0次)
请问,在多次(包括0次)挥动金棒后,所有分身所采摘的蟠桃数量之和的最大可能值是多少?

输入格式:


输入包括两行。
第一行输入一个整数 N(2 ≤ N ≤ 105),表示道路的数量,
第二行输入一个仅包含 工、Q,且长度为 N 的字符串 S,其中若S;为 工 表示道路i有天兵把守,为 Q 表示道路讠没有天兵把守(数据保证至少有1条道路有天兵把守)。

输出格式:


输出一个整数,代表所有分身采摘蟠桃数量之和的最大可能值。

样例输入:

3

L Q L

样例输出:

1

解题思路:

为了更好地理解并解决这个问题,我们可以通过一些巧妙的定义和方法来简化问题的求解过程。首先,我们不需要单独记录每个分身在每个时刻的采摘数量,而是引入一个新的变量c[i],表示当前位于小路i的分身的采摘数量。

定义c[i]:

c[i]表示当前在小路i上的分身的采摘数量。这样一来,无论什么时候挥动金箍棒,每个采摘数量都会与某个小路关联,而不是与个特定的分身关联。

定义left[i]:

接下来,为了进一步简化问题,对于每个小路i,我们定义left[i]为从小路i向左最近的有天兵把守的小路的距离。特别地,如果小路i上有天兵把守,则left[i]=0。

推导过程:

1. 初始状态:

在初始时刻,每个小路i上的分身采摘数量为c[i],且所有分身的初始采摘数量均为0。

2. 移动分析:

每次挥动金箍棒,所有分身都会向右移动一条小路。我们关心的是分身在移动过程中遇到的天兵把守的情况。

3. 采摘数量的限制:

由于left[i]表示从小路i向左最近的有天兵把守的小路的距离,因此对于任何时刻,c[i]的最大值为left[i]。这是为移动过程中,分身在遇到有天兵把守的小路之前,最多移动了left[i]次。因此,c[i]的最大值为left[i].

4. 最大采摘数量的实现:

如果我们挥动金箍棒至少left[i]次,那么可以保证c[i]达到left[i]。在最多挥动N-1次后,c[i]将会达到left[i]的最大值。

5. 结果求解:

综上所述,最终所有分身的采摘数量之和的最大可能值为所有left[i]的总和,即∑μ1left[i]

在具体实现时,我们无需去真正地去定义c[]数组和left[]数组,而是可以从前往后遍历每一条小路,维护一个变量c来计算连续的、没有天兵把守的小路的长度,并根据求和公式2来计算 ∑N1left[i]。这点大家应该还挺好理解的。

时间复杂度为O(N)。

程序如下:

#define _CRT_SECURE_NO_WARNINGS  1
#pragma warning(disable:6031)
//解决VS_2022中scanf返回值被忽略的问题
/*#include<bits/stdc++.h>_VS默认情况下并不支持 stdc++.h 这个头文件,
所以我们采用如下头文件来编译运行代码*/
//考虑到大家对这些头文件比较陌生,所以我们来详解一下这些头文件
#include <iostream>
/*#include <iostream> 是C++程序中非常常见的一条预处理指令,它包含了iostream库。
iostream库提供了C++程序中用于处理标准输入/输出流的基本功能。
这个库中定义了一些重要的类和对象,以及与输入/输出相关的函数。
以下是iostream库中的一些关键组件:

std::istream 类:这是一个输入流类,用于从输入设备(如键盘、文件等)读取数据。

std::ostream 类:这是一个输出流类,用于向输出设备(如屏幕、文件等)写入数据。

std::cin 对象:这是一个std::istream类型的对象,表示标准输入流(通常是键盘输入)。
它是std::istream类的一个实例。

std::cout 对象:这是一个std::ostream类型的对象,表示标准输出流(通常是屏幕输出)。
它是std::ostream类的一个实例。

std::cerr 对象:这是一个std::ostream类型的对象,表示标准错误流。
它通常用于输出错误消息。
与std::cout相比,std::cerr默认情况下是非缓冲的,这意味着错误消息会立即显示,而不是等待缓冲区被填满。

std::clog 对象:这是一个std::ostream类型的对象,表示标准日志流。
它与std::cerr类似,但用于输出日志消息。

除了这些基本组件之外,iostream库还包括了其他与流处理相关的类,
例如std::stringstream、std::ifstream和std::ofstream等。
这些类分别用于处理字符串流、文件输入流和文件输出流。*/
#include <vector>
/*
(1)在C++中,vector是一种使用非常广泛的容器类,属于标准模板库(STL)的一部分。
它能够存储任意类型的对象,从基本类型如int、float到自定义类型都可以。
更重要的是,vector支持动态扩展,不需要程序员手动管理内存,极大地提高了编程效率和安全性。
(2)vector是变长数组,支持随机访问,不支持在任意位置O(1)插入。为了保证效率,元素的增删一般应该在末尾进行。
(3)在C++的标准模板库(STL)中,vector是一个非常有用的动态数组容器。它允许我们存储可变大小的同类型元素序列,
并且能够动态地增长和缩小。由于其灵活性和易用性,vector在C++编程中得到了广泛的应用。
*/
#include <algorithm>
/*
#include <algorithm> 是C++中一个常用的预处理指令,它包含了algorithm库。
这个库提供了大量用于操作序列(例如数组、向量、列表等容器)的通用算法,这些算法包括查找、排序、复制、移动、修改和其他操作。
以下是algorithm库中一些常用函数接口的概述:

std::sort(begin, end):对序列进行排序。begin和end是序列的起始和结束迭代器。

std::stable_sort(begin, end):对序列进行稳定排序(保持相等元素的相对顺序)。

std::reverse(begin, end):反转序列中的元素顺序。

std::find(begin, end, value):查找序列中第一个等于value的元素。如果找到,返回指向该元素的迭代器,否则返回end。

std::count(begin, end, value):计算序列中等于value的元素个数。

std::min_element(begin, end):查找序列中的最小元素。返回指向最小元素的迭代器。

std::max_element(begin, end):查找序列中的最大元素。返回指向最大元素的迭代器。

std::copy(source_begin, source_end, dest_begin):从源序列复制元素到目标序列。返回指向目标序列末尾的迭代器。

std::move(source_begin, source_end, dest_begin):将源序列的元素移动到目标序列。

std::remove(begin, end, value):移除序列中所有等于value的元素。返回指向新序列末尾的迭代器。

std::unique(begin, end):移除序列中所有连续重复的元素。返回指向新序列末尾的迭代器。

std::replace(begin, end, old_value, new_value):将序列中所有等于old_value的元素替换为new_value。

std::fill(begin, end, value):将序列中的所有元素设置为value。

std::for_each(begin, end, function):对序列中的每个元素应用function。

这只是algorithm库中众多函数的一部分。在实际编程中,这个库为处理序列数据提供了非常强大的功能。
使用这些通用算法可以简化代码,提高代码的可读性和可维护性。
*/
using namespace std;//命名空间
int main() {
	//对用户输入的一串字符进行处理;
	int N; cin >> N;//声明整型变量N,用于接收用户输入的一个整数
	vector<int>A(N);//使用cin从标准输入读取N并动态创建一个大小为N的vector<int类型的数组A;
	for (int i = 0; i < N; i++) {//for循环;遍历范围从0~N-1;
		char x;
		cin >> x;
		if (x == 'L') A[i] = 0;
		else A[i] = 1;
	}
	//用于将向量A中第一个遇到的0元素移动到最前面的位置,然后终止循环
	for (int i = 0; i < N; i++) {//for循环;遍历整型向量A中的元素
		if (A[i] == 0) {//调用std::rotaate
			rotate(A.begin(), A.begin() + i + 1, A.end());//由i+1开始到向量结尾的所有元素向前移动一位,使得原本在i处的0元素移动到向量的最前面
			break;//找到并移动了第一个0,跳出循环
		}
	}
	//用于计算给定数组A中连续为1的子段之间的空0元素的数量
	long long c = 0, ans = 0;
	/*long long c=0 长整型变量;用于记录遇到的第一个1之前连续的0的个数;
	  long long ans=0 用于存储最终结果*/
	for (int i = 0; i < N; i++) {//for循环,遍历数组A的每个元素,从索引i = 0到N - 1
		if (A[i] == 0) {
			ans += c * (c + 1) / 2;//组合公式计算
			c = 0;
		}
		if (A[i] == 1) c++;
	}
	//循环结束
	cout << ans << '\n';//ans包含了所有有效空0元素的序列和,最后通过cout将其输出,并返回0表示程序正常结束。
	return 0;
}

运行结果:

标签:std,蟠桃,begin,end,小路,大闹,算法,序列,分身
From: https://blog.csdn.net/2301_80508598/article/details/141143919

相关文章

  • 常见算法
    //基本查找,顺序查找:从0开始依次向后查找,找到返回对应索引值,未找到返回-1#include<stdio.h>intOrder(intarr[],intlen,intflag);intmain(){intarr[5]={1,2,3,4,5};intlen=sizeof(arr)/sizeof(int);intflag=5;inti=0;intnum=Order(arr,len,flag);printf("%d"......
  • 「代码随想录算法训练营」第三十九天 | 动态规划 part12
    115.不同的子序列题目链接:https://leetcode.cn/problems/distinct-subsequences/文章讲解:https://programmercarl.com/0115.不同的子序列.html题目难度:困难视频讲解:https://www.bilibili.com/video/BV1fG4y1m75Q/题目状态:看题解思路:动态规划数组初始化创建一个二维动......
  • 华为OD笔试机试 - 攀登者2 (python/c++/java 2024年C卷D卷真题算法)
    华为OD机试(C卷+D卷)2024真题目录(Java&c++&python)题目描述攀登者喜欢寻找各种地图,并且尝试攀登到最高的山峰。地图表示为一维数组,数组的索引代表水平位置,数组的元素代表相对海拔高度。其中数组元素0代表地面。例如:[0,1,2,4,3,1,0,0,1,2,3,1,2,1,0],代表如下图所示的......
  • 混合策略改进的蜣螂算法(IDBO)优化长短期记忆神经网络原理及matlab代码
    目录0引言1数学模型2模型对比3matlab代码3.1改进的主代码3.2IDBO-LSTM4视频讲解0引言针对DBO算法全局探索能力不足、易陷入局部最优以及收敛精度不理想等问题,多为学者提出了混合多策略改进的蜣螂优化算法(IDBO)。主要混合策略改进首先是采用混沌映射结合随机反......
  • 混合策略改进的蜣螂算法(IDBO)优化支持向量机原理及matlab代码
    目录0引言1数学模型2模型对比3matlab代码3.1改进的主代码3.2IDBO-SVM4视频讲解0引言针对DBO算法全局探索能力不足、易陷入局部最优以及收敛精度不理想等问题,多为学者提出了混合多策略改进的蜣螂优化算法(IDBO)。主要混合策略改进首先是采用混沌映射结合随机反向......
  • 广度优先算法 BFS总结(算法详解+模板+例题)
    一.bfs是什么广度优先搜索(Breadth-FirstSearch,简称BFS),是一种图遍历算法。它从给定的起始节点开始,逐层地向外扩展,先访问起始节点的相邻节点,然后再访问相邻节点的相邻节点,以此类推,直到遍历完所有可达节点。二.基本思路1.一直往前走,直到到达终点。2.遇到分岔路口直接分出几条......
  • VUE DIFF算法原理
    Vue的Diff算法是虚拟DOM实现中的核心部分,它在视图更新时比较新旧虚拟DOM树并高效更新实际DOM。一、什么是Diff算法?Diff算法用于在虚拟DOM更新时,通过比较新旧两棵虚拟DOM树,找出最小差异并将这些变化应用到实际DOM上。Vue采用了一种高效的算法,只对同层级节点进......
  • KMP算法——理解 next 数组
    !注意!本文与《王道》,《严书》有所不同,字符串均从第0位开始,next数组没有添加常数1。博客为梳理思路所用,难免纰漏,希望不吝赐教。在字符串匹配中,设m为待匹配的主串S长度,n为找寻的模式串T长度。如:在主串S='ababc'中寻找模式串T='abc'则字符串匹配算法返回S中第......
  • Python实现CNN(卷积神经网络)对象检测算法
    目录1.引言2.对象检测的基本原理2.1对象检测的目标2.2常见对象检测方法2.2.1基于滑动窗口的传统方法2.2.2基于区域提议的现代方法2.2.3单阶段检测器2.3本次实现的检测方法3.代码实现3.1环境准备3.2数据准备与预处理3.3构建CNN模型3......
  • 【机器学习算法】梯度提升决策树
    梯度提升决策树(GradientBoostingDecisionTrees,GBDT)是一种集成学习方法,它通过结合多个弱学习器(通常是决策树)来构建一个强大的预测模型。GBDT是目前最流行和最有效的机器学习算法之一,特别适用于回归和分类任务。它在许多实际应用中表现出色,包括金融风险控制、搜索排名、......