洛谷pP2708 硬币翻转

洛谷pP2708 硬币翻转

问题描述

给定长度为 $n$ 的 $01$ 串,定义一次操作为把一个区间 $[l,r]$ 内的 $0$ 变成 $1$,$1$ 变成 $0$。求最少操作次数使得 $01$ 串变成 $11\cdots 1$ 或者 $00\cdots 0$。

约定:

  • 区间 $[l,r]$ 指 $[l,r]$ 之间的字符,$1\leq l\leq r\leq n$。

输入格式

第一行一个整数 $n$,表示字符串长度。

第二行一个长度为 $n$ 的 $01$ 串。

输出格式

输出一个数,表示最少操作次数。

样例输入1

3
101

样例输出1

2

样例说明1

将区间 $[1,2]$ 翻转一次,将区间 $[2,3]$ 翻转一次。

样例输入2

5
11111

样例输出2

0

样例说明2

$01$ 串已经为 $11111$。

样例输入3

6
101010

样例输出3

3

样例说明3

将区间 $[2,3]$ 翻转一次,将区间 $[4,5]$ 翻转一次,将区间 $[6,6]$ 翻转一次。

思路分析

我们可以定义一个差异数组 $d$,用来记录 $01$ 串中每一个位置上的字符与目标串 $11\cdots 1$ 或者 $00\cdots 0$ 的字符差异。

最后问题被转化为将这个差异数组的和转换成 $0$ 的问题,因为每一次翻转操作都会将差异数组的和减少 $2\Delta$。

所以问题被转化为了求差异数组中连续的一些子区间,将其和转化成 $0$ 的问题,这个问题可以使用前缀和和哈希表优化求解。

代码实现

n = int(input())
s = input()

d = []
for i in range(n):
    if s[i] == '0':
        d.append(1)
    else:
        d.append(-1)

pre = [0] * (n + 1)
for i in range(n):
    pre[i + 1] = pre[i] + d[i]

cnt = {}
ans = 0
for i in range(n + 1):
    x = pre[i]
    ans += cnt.get(x, 0)
    cnt[x] = cnt.get(x, 0) + 1
print(ans)

总结

本文是对洛谷 pP2708 硬币翻转题目的一个详细解答,通过前缀和和哈希表的优化,实现了对该问题的高效求解。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:洛谷pP2708 硬币翻转 - Python技术站

(0)
上一篇 2023年3月28日
下一篇 2023年3月28日

相关文章

  • C/C++举例讲解关键字的用法

    C/C++关键字的用法详解 C/C++是一种广泛使用的编程语言,其中关键字是语言的基本构建块。在本攻略中,我们将详细讲解C/C++中一些常用关键字的用法,并提供示例说明。 1. if-else语句 if-else语句用于根据条件执行不同的代码块。它的语法如下: if (condition) { // 如果条件为真,执行这里的代码 } else { // 如果…

    other 2023年7月29日
    00
  • Mysql创建json字段索引的两种方式

    下面是关于MySQL创建JSON字段索引的两种方式的攻略。 方式一:使用虚拟列 准备工作 在 MySQL 5.7.8 版本及以后,支持通过自定义虚拟列的方式对表中的 JSON 字段进行索引。因此,在开始之前需要确保你的 MySQL 版本不低于 5.7.8。 操作步骤 接下来,我们假设有一个名为 users 的表,其中有一个 JSON 字段 info,现在我们…

    other 2023年6月25日
    00
  • JS中Promise的使用及封装方式

    JS中Promise的使用及封装方式 什么是Promise Promise 是 JS 中一种处理异步操作的机制。在 Promise 中,异步操作被封装成了一个对象,可以通过 then() 方法来处理异步操作的返回结果。 Promise 提供了三种状态:pending(等待态)、fulfilled(完成态)和rejected(拒绝态)。 pending:初始状…

    other 2023年6月25日
    00
  • 电脑IP地址在哪里查看?如何快速查看电脑IP地址?

    电脑IP地址的查看 电脑的IP地址是用于在网络中标识和定位设备的唯一标识符。在Windows和Mac操作系统中,可以通过以下步骤快速查看电脑的IP地址。 在Windows操作系统中查看IP地址 打开开始菜单,点击\”设置\”图标。 在设置窗口中,点击\”网络和Internet\”选项。 在\”网络和Internet\”页面中,点击\”状态\”选项卡。 在状态…

    other 2023年7月29日
    00
  • android应用框架-volley网络通信框架

    以下是关于“Android应用框架-Volley网络通信框架”的完整攻略,包括定义、特点、使用方法、示例说明和注意事项。 定义 Volley是一款由Google开发的Android网络通信框架,可以帮助开发者快速、便地进行网络通信。Volley支持HTTP请求、图片加载、JSON解析等功能,具有高效、简单可定制等特点。 特点 Volley的特点包括: 高效:…

    other 2023年5月8日
    00
  • Android使用自定义PageTransformer实现个性的ViewPager动画切换效果

    Android使用自定义PageTransformer实现个性的ViewPager动画切换效果攻略 在Android开发中,ViewPager是一个常用的控件,用于实现页面切换效果。通过自定义PageTransformer,我们可以实现个性化的ViewPager动画切换效果。下面是详细的攻略,包含两个示例说明。 步骤一:创建自定义的PageTransform…

    other 2023年8月20日
    00
  • iOS实现账号、密码记住功能

    开启记住用户信息功能 在iOS中,实现用户账号和密码记住功能需要进行以下步骤: 创建NSUserDefaults用于存储用户信息 在登录页面添加两个switch控件,一个控制账号的记住,一个控制密码的记住 当用户选择“记住”选项时,通过NSUserDefaults将数据存储在本地 在下一次打开应用时,从NSUserDefaults中读取用户数据并填充到登录页…

    other 2023年6月27日
    00
  • iOS复数cell下优雅的代码结构详解

    iOS复数cell下优雅的代码结构详解,主要是针对UITableView及其性能优化的一些技巧和建议。 一、为大型表格准备 1.1 使用复数section/cell 对于大型表格,我们通常会使用UITableViewCell的复用机制来避免出现性能问题。同时,使用复数的section/cell也能够让我们避免一个section/cell变得过于庞大。 举个例…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部