不含101的数_200分——二进制数 / 动态规划 / 数位DP_2023A卷

2023-11-07

不含101的数

题目描述:

  小明在学习二进制时,发现了一类不含 101的数,也就是:
  将数字用二进制表示,不能出现 101 。
  现在给定一个整数区间 [l,r] ,请问这个区间包含了多少个不含 101 的数

输入输出描述:

输入描述:

  输入的唯一一行包含两个正整数 l, r( 1 ≤ l ≤ r ≤ 10^9)。

输出描述:

  输出的唯一一行包含一个整数,表示在 [l,r] 区间内一共有几个不含 101 的数。

示例1:

输入:
	1 10
输出:
	8
说明:
区间 [1,10] 内, 
5 的二进制表示为 101 ,
10的二进制表示为 1010 ,
因此区间 [ 1 , 10 ] 内有 10−2=8 个不含 101的数。

示例2:

输入:
	10 20
输出:
	7
说明:
	区间 [10,20] 内,
	满足条件的数字有 [12,14,15,16,17,18,19] 
	因此答案为 7。

解题思路1:

两种方法。
第一种方法,利用连续整数的二进制变化规律来解题
第二种方法,动态规划
方法一思路:
已知十进制数 n 的二进制序列为 b1,则十进制的 n + 1 对应的二进制序列 b2 为:
b 2 = { " 1 " + b 1 每一位都变成 0 b 1 中全是 1 将 b 1 中从右往左出现的第一个 0 及其右边的 1 都变成 1 b 1 中含有 0 b2 = \begin{cases} "1" + b1每一位都变成0 & b1中全是 1\\ 将b1中从右往左出现的第一个 0 及其右边的 1 都变成 1 & b1中含有0 \end{cases} b2={"1"+b1每一位都变成0b1中从右往左出现的第一个0及其右边的1都变成1b1中全是1b1中含有0
故可推测出是否含有“101”的规律:
  b1中为全1时,不会出现“101”
  b1中为含有0时,可能会出现“101”(从右往左第一个0变成1后出现“101”、或者从右往左第一个0的左边本来就有“101”)
如下面两幅图所示:
规律总结
1-20对应的二进制序列变化规律

代码:

public static void main(String[] args) {
	Scanner scanner = new Scanner(System.in);
	int left = scanner.nextInt();
	int right = scanner.nextInt();
	StringBuilder sb = new StringBuilder();
	long count = 0;
	long sum = right - left + 1;

	// 求 left 的二进制
	int tmp = left - 1;
	while (tmp != 0) {
		sb.append(tmp % 2);
		tmp /= 2;
	}

	// 如果 left 对应的二进制中含有“101”,记录 101 的在二进制字符串中的下标
	int indexOf = sb.toString().indexOf("101");
	int pre = indexOf == -1 ? Integer.MAX_VALUE : indexOf;
	while (left <= right) {
		int oldLen = sb.length();
		int index = oldLen - 1;

		// 从右往左找到第一个 0
		while (index >= 0 && sb.charAt(index) != '0') {
			index--;
		}

		// 0 的右边的所有 1 替换成 0
		if (index < 0) {
			// sb中全是 1,则说明二进制的位数需要增加一位才能表示:左边第一位为 1,其余都是 0。且不会出现”101“
			pre = pre == sb.length() - 1 ? sb.length() : pre;
			sb.append('1');
			index = 0;
		} else {
			if (index - 2 >= 0 && sb.charAt(index - 2) == '1' && sb.charAt(index - 1) == '0') {
				// 0 的左边是"10",则会出现"101": 将 100 --> 101
				count++;
				// 更新“101”出现的下标: pre
				pre = Math.min(pre, index);
			} else {
				// 在 index 的左边存在 101
				if (pre != Integer.MAX_VALUE && pre < index) {
					count++;
				}
				// 更新“101”出现的下标: pre
				if (index < pre) {
					pre = sb.length();
				}
			}
		}

		// 从右往左找到第一个 0 后,把这个 0 改成 1,把 0 的右边的 1 全部改成 0
		sb.setCharAt(index++, '1');
		while (index < sb.length()) {
			sb.setCharAt(index, '0');
			index++;
		}
		left++;
	}

	System.out.println(sum - count);
}

解题思路2:

数位DP的套路解法;
数位DP可以看这个文章:
数位 DP 通用模板,附题单(Python/Java/C++/Go)

代码:

static char[] chars;
static int[][][] memo;
public static void main(String[] args) {
	Scanner scanner = new Scanner(System.in);
	int left = scanner.nextInt();
	int right = scanner.nextInt();
	
	System.out.println(myDp(right) - myDp(left-1));
}

// 统计出十进制数 [0, num] 中有多少个数的二进制中包含有 "101"
public static int myDp(int num) {
	// 初始化记忆数组
	chars = Integer.toBinaryString(num).toCharArray();
	memo = new int[chars.length][2][2];
	for (int i = 0; i < memo.length; i++) {
		for (int j = 0; j < 2; j++) {
			Arrays.fill(memo[i][j], -1);
		}
	}

	return f(0, 0, 0, true);
}

/**
 * 填写二进制序列的第 i 位
 * @param i 二进制序列的第 i 位
 * @param pre 上一个填写的数字
 * @param prepre 上上个填写的数字
 * @param isLimit 高位填写过的数字是否和 num 的二进制一样,是的话当前位会受到限制
 * @return
 */
private static int f(int i, int pre, int prepre, boolean isLimit) {
	// 如果能够成功的填写出长度和 num 一样的二进制数,说明该路径解可行
	if (i == chars.length) {
		return 1;
	}

	// 如果已经被搜索过,则直接返回
	if (!isLimit && memo[i][pre][prepre] != -1) {
		return memo[i][pre][prepre];
	}

	int res = 0;
	int up = isLimit ? chars[i] - '0' : 1;
	for (int d = 0; d <= up; d++) {
		// 如果当前位填写 1,且前面两位是 0、1,则会组成 "101"
		if (!(d == 1 && pre == 0 && prepre == 1)) {
			res += f(i + 1, d, pre, isLimit && d == up);
		}
	}

	// 记忆化
	if (!isLimit) {
		memo[i][pre][prepre] = res;
	}

	return res;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

不含101的数_200分——二进制数 / 动态规划 / 数位DP_2023A卷 的相关文章

  • Java new Date() 打印

    刚刚学习 Java 我知道这可能听起来很愚蠢 但我不得不问 System out print new Date 我知道参数中的任何内容都会转换为字符串 最终值是 new Date 返回对 Date 对象的引用 那么它是如何打印这个的呢 Mo
  • Spring Batch 多线程 - 如何使每个线程读取唯一的记录?

    这个问题在很多论坛上都被问过很多次了 但我没有看到适合我的答案 我正在尝试在我的 Spring Batch 实现中实现多线程步骤 有一个包含 100k 条记录的临时表 想要在 10 个线程中处理它 每个线程的提交间隔为 300 因此在任何时
  • 给定两个 SSH2 密钥,我如何检查它们是否属于 Java 中的同一密钥对?

    我正在尝试找到一种方法来验证两个 SSH2 密钥 一个私有密钥和一个公共密钥 是否属于同一密钥对 我用过JSch http www jcraft com jsch 用于加载和解析私钥 更新 可以显示如何从私钥 SSH2 RSA 重新生成公钥
  • Spring Data JPA 应用排序、分页以及 where 子句

    我目前正在使用 Spring JPA 并利用此处所述的排序和分页 如何通过Spring data JPA通过排序和可分页查询数据 https stackoverflow com questions 10527124 how to query
  • Mockito when().thenReturn 不必要地调用该方法

    我正在研究继承的代码 我编写了一个应该捕获 NullPointerException 的测试 因为它试图从 null 对象调用方法 Test expected NullPointerException class public void c
  • Spring @RequestMapping 带有可选参数

    我的控制器在请求映射中存在可选参数的问题 请查看下面的控制器 GetMapping produces MediaType APPLICATION JSON VALUE public ResponseEntity
  • 无法解析插件 Java Spring

    我正在使用 IntelliJ IDEA 并且我尝试通过 maven 安装依赖项 但它给了我这些错误 Cannot resolve plugin org apache maven plugins maven clean plugin 3 0
  • 斯坦福 NLP - 处理文件列表时 OpenIE 内存不足

    我正在尝试使用斯坦福 CoreNLP 中的 OpenIE 工具从多个文件中提取信息 当多个文件 而不是一个 传递到输入时 它会给出内存不足错误 All files have been queued awaiting termination
  • Java TestNG 与跨多个测试的数据驱动测试

    我正在电子商务平台中测试一系列商店 每个商店都有一系列属性 我正在考虑对其进行自动化测试 是否有可能有一个数据提供者在整个测试套件中提供数据 而不仅仅是 TestNG 中的测试 我尝试不使用 testNG xml 文件作为机制 因为这些属性
  • 在两个活动之间传输数据[重复]

    这个问题在这里已经有答案了 我正在尝试在两个不同的活动之间发送和接收数据 我在这个网站上看到了一些其他问题 但没有任何问题涉及保留头等舱的状态 例如 如果我想从 A 类发送一个整数 X 到 B 类 然后对整数 X 进行一些操作 然后将其发送
  • JRE 系统库 [WebSphere v6.1 JRE](未绑定)

    将项目导入 Eclipse 后 我的构建路径中出现以下错误 JRE System Library WebSphere v6 1 JRE unbound 谁知道怎么修它 右键单击项目 特性 gt Java 构建路径 gt 图书馆 gt JRE
  • 在 Mac 上正确运行基于 SWT 的跨平台 jar

    我一直致力于一个基于 SWT 的项目 该项目旨在部署为 Java Web Start 从而可以在多个平台上使用 到目前为止 我已经成功解决了由于 SWT 依赖的系统特定库而出现的导出问题 请参阅相关thread https stackove
  • 仅将 char[] 的一部分复制到 String 中

    我有一个数组 char ch 我的问题如下 如何将 ch 2 到 ch 7 的值合并到字符串中 我想在不循环 char 数组的情况下实现这一点 有什么建议么 感谢您花时间回答我的问题 Use new String value offset
  • 如何从终端运行处理应用程序

    我目前正在使用加工 http processing org对于一个小项目 但是我不喜欢它附带的文本编辑器 我使用 vim 编写所有代码 我找到了 pde 文件的位置 并且我一直在从 vim 中编辑它们 然后重新打开它们并运行它们 重新加载脚
  • 在mockito中使用when进行模拟ContextLoader.getCurrentWebApplicationContext()调用。我该怎么做?

    我试图在使用 mockito 时模拟 ContextLoader getCurrentWebApplicationContext 调用 但它无法模拟 here is my source code Mock org springframewo
  • 静态变量的线程安全

    class ABC implements Runnable private static int a private static int b public void run 我有一个如上所述的 Java 类 我有这个类的多个线程 在里面r
  • 编译器抱怨“缺少返回语句”,即使不可能达到缺少返回语句的条件

    在下面的方法中 编译器抱怨缺少退货声明即使该方法只有一条路径 并且它包含一个return陈述 抑制错误需要另一个return陈述 public int foo if true return 5 鉴于Java编译器可以识别无限循环 https
  • 捕获的图像分辨率太大

    我在做什么 我允许用户捕获图像 将其存储到 SD 卡中并上传到服务器 但捕获图像的分辨率为宽度 4608 像素和高度 2592 像素 现在我想要什么 如何在不影响质量的情况下获得小分辨率图像 例如我可以获取或设置捕获的图像分辨率为原始图像分
  • 当我从 Netbeans 创建 Derby 数据库时,它存储在哪里?

    当我从 netbeans 创建 Derby 数据库时 它存储在哪里 如何将它与项目的其余部分合并到一个文件夹中 右键单击Databases gt JavaDB in the Service查看并选择Properties This will
  • 将 List 转换为 JSON

    Hi guys 有人可以帮助我 如何将我的 HQL 查询结果转换为带有对象列表的 JSON 并通过休息服务获取它 这是我的服务方法 它返回查询结果列表 Override public List

随机推荐

  • Unity中同时修改物体及其所有子物体层级

    简单说一下思路 首先你得判定当前物体是否有子物体 没有的话就直接设置层级 有的话就再回到1 继续判断子物体下是否还有子物体 接下来结合代码再好好理解一下 private void ChangeLayer Transform transfor
  • matlab实现牛顿下山法

    说起牛顿下山法 首先要提牛顿法 牛顿法是求解非线性方程的一个重要方法 具体可以点击牛顿法 虽然牛顿法作为一个二阶的迭代收敛方法 但是其对于函数和初始点的要求都比较高 而牛顿下山法则是有效降低这些要求的一种技巧 牛顿下山法的迭代公式如下 x
  • [C/C++] 创建后台接受命令程序

    C C 多线程时 运行时输入自定义参数 达到控制线程的目的 基础概念 线程 线程是操作系统能够进行运算调度的最小单位 它被包含在进程之中 进程包含一个或者多个线程 进程可以理解为完成一件事的完整解决方案 而线程可以理解为这个解决方案中的的一
  • 弹性布局-更优秀的Flex

    Flex布局详解 浮动布局的优缺点 图文的环绕显示 浮动元素 同行显示 适配性更好 忘记清浮动 高度坍塌 flex布局的优缺点 IE10以下不支持 用来做布局的 很方便 flex布局 flex flexible 弹性布局 移动端用的最多 P
  • LeetCode——345. 反转字符串中的元音字母

    反转字符串中的元音字母 题目 思路 代码 结果 题目 给你一个字符串 s 仅反转字符串中的所有元音字母 并返回结果字符串 元音字母包括 a e i o u 且可能以大小写两种形式出现 思路 没有什么难度 很简单的数组判断交换 代码 clas
  • 操作系统——启动操作系统及ucore-lab0 coding

    花了一周多时间把操作系统的课程看了一遍 晚上结课的时候尝试性地想看着笔记的标题回忆一下内容 发现 嗯 一片混沌 趁热打铁做个总结吧 辅以uCoreLab上的coding 一个走 1 操作系统的启动 未启动前 os和Bootloader都存放
  • 图形学/OpenGL/3D数学/Unity

    1 场景管理的数据结构 总结 游戏开发最常用的空间数据结构是四叉 八叉树和BVH树 而BSP树基本上只能应用于编辑器上 k d树则只能用在特殊问题应用场景 2 帧同步与状态同步 https gameinstitute qq com comm
  • lattice 包中的直方图绘制

    1 直方图 library lattice install packages nutshell library nutshell histogram DBWT DPLURAL data births2006 smpl main births
  • 记一次Swagger页面报错/error 404的排查过程

    记一次Swagger页面报错 error 404的排查过程 使用springfox swagger ui展示的页面如下 Maven引用 使用springfox swagger ui展示的页面如下 说是没有为 error这个路径指明确定的映射
  • Java中的注解和反射

    文章目录 Java中的注解和反射 一 注解 1 1注解Annotation的作用 1 2注解Annotation的格式 1 3注解Annotation在哪里使用 1 4实例 二 内置注解 三 元注解 四 自定义注解 五 静态和动态语言 5
  • 2022年浙江省中职组“网络空间安全”赛项模块B--Windows渗透测试

    2022年中职组浙江省 网络空间安全 赛项 B 1 Windows渗透测试 一 竞赛时间 420分钟 共计7小时 吃饭一小时 二 竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第 阶段 单兵模式系统渗透测试 任务一 Windows
  • Notepad++ 文件丢失了,找回历史文件方法

    Notepad 文件丢失了 找回历史文件方法 C Users 你当前用户的用户名 AppData Roaming Notepad backup
  • Linux防火墙iptables(二)之SNAT和DNAT

    目录 一 SNAT 1 概述 2 开启SNAT的命令 3 SNAT转换1 固定的公网IP地址 4 SNAT转换2 非固定的公网IP地址 共享动态IP地址 5 实验 二 DNAT 1 DNAT应用环境 2 DNAT原理 3 DNAT转换前提条
  • 解决react-native-image-picker在RN0.6以上上调不起相机问题

    1 需要link react native link react native image picker 2 在android settings gradle文件中添加如下代码 include react native image pick
  • 算法设计与分析-DP习题

    7 1 最小路径和 给定一个m行n列的矩阵 从左上角开始每次只能向右或者向下移动 最后到达右下角的位置 路径上的所有数字累加起来作为这条路径的和 求矩阵的最小路径和 输入格式 输入第一行 两个正整数m和n 1 lt m n lt 1000
  • Altium Designer 学习笔记(原理图库)

    1 AD工程的组成部分 源文件 原理图 PCB图 库文件 原理图库 PCB原件库 一定要建工程 不要只建原理图和PCB 建立了工程才能在原理图和PCB之间建立联系 2 绘制原理图库 电阻容 放置引脚 快捷键 P P 在放置的过程中按TAB可
  • opengl_shader在线教程,GLSL  着色器语言学习入门学习

    下面2个网址对GLSL 着色器语言学习入门学习挺有帮助的 https thebookofshaders com 07 lan ch opengl入门教程 https learnopengl cn github io
  • Qt扫盲-QFile理论总结

    QFile理论总结 1 概述 2 直接操件文件 3 用 流 方式 操作 文件 1 读取文件 2 写文本文件 3 二进制流读写 4 静态函数 5 不同系统存在的问题 1 概述 QFile 类是一种用于读取和写入文本和二进制文件资源的 I O
  • 数据结构(十七) -- 树(九) --B树B+树

    数据结构演示网址 数据结构演示地址 1 出现背景 B树B 树目的 为了硬盘快速读取数据 降低IO操作次数 而设计的一种平衡的多路查找树 二叉查找树 AVL树 红黑树等都属于二叉树的范围 查找的时间复杂度是O log 2N 与树的深度相关 那
  • 不含101的数_200分——二进制数 / 动态规划 / 数位DP_2023A卷

    不含101的数 题目描述 小明在学习二进制时 发现了一类不含 101的数 也就是 将数字用二进制表示 不能出现 101 现在给定一个整数区间 l r 请问这个区间包含了多少个不含 101 的数 输入输出描述 输入描述 输入的唯一一行包含两个