枚举(蓝桥练习)(反倍数、特别数的和、找到最多的数、小蓝的漆房、小蓝和小桥的挑战)

news2025/2/24 3:37:42

目录

一、枚举算法介绍

二、解空间的类型

三、循环枚举解空间

四、例题

(一、反倍数)

(二、特别数的和)

(三、找到最多的数)

(四、小蓝的漆房)

(五、小蓝和小桥的挑战)


一、枚举算法介绍

枚举算法是一种基本的算法思想,它通过穷举所有可能的情况来解决问题。它的基本思想是将问题的解空间中的每个可能的解都枚举出来,并进行验证和比较,找到满足问题条件的最优解或者所有解。
枚举算法适用于问题规模较小、解空间可穷举的情况。它的优点是简单直观,不需要复杂的数学推导,易于实现。但是,由于需要穷举所有可能的情况,对于问题规模较大的情况,枚举算法的时间复杂度可能会非常高,效率较低。

二、解空间的类型

解空间可以是一个范围内的所有数字(或二元组、字符串等数据),或者满足某个条件的所有数字
当然也可以是解空间树,一般可分为子集树和排列树,针对解空间树,需要使用回溯法进行枚举(在后面讲到搜索的时候会讲到)。
我们目前仅使用循环去暴力枚举解空间,具体的解空间类型需要根据题目来理解构造。

三、循环枚举解空间

1.首先确定解空间的维度,即问题中需要枚举的变量个数。例如当题目要求的是满足条件的数字时,我们可以循环枚举某个范围内的数字。如果要求的是满足条件的二元组,我们可以用双重循环分别枚举第一个和第二个变量,从而构造出一个二元组。
2.对于每个变量,确定其可能的取值范围。这些范围可以根据问题的性质和约束条件来确定。
这一步往往是时间复杂度优化的关键。
3.在循环体内,针对每个可能解进行处理。可以进行问题的验证、计算、输出等操作

四、例题

(一、反倍数)

用户登录

题目描述
给定三个整数 a,b,c,如果一个整数既不是 a的整数倍也不是b的整数倍还不是 c的整数倍,则这个数称为反倍数。
请问在 1至 n 中有多少个反倍数。
输入描述
输入的第一行包含一个整数 n。
第二行包含三个整数 a,b,c,相邻两个数之间用一个空格分隔。其中,1≤n<1000000,1≤a≤n,1≤b≤n,1≤c≤n
输出描述
输出一行包含一个整数,表示答案。

#define  _CRT_SECURE_NO_WARNINGS 1
#include<bits/stdc++.h>
using namespace std; // 使用std命名空间,以便直接使用cout、cin等,而不是std::cout、std::cin

int a, b, c;

bool f(int x)
{
    return x % a != 0 && x % b != 0 && x % c != 0;
}

int main()
{
    int n; cin >> n;
    cin >> a >> b >> c;
    int ans = 0;
    for (int i = 1; i <= n; ++i)
    {
        if (f(i))ans ++;
    }
    cout << ans << '\n';
    return 0;
}

(二、特别数的和)

用户登录

题目描述
小明对数位中含有 2、0、1、9的数字很感兴趣(不包括前导 0),在1到40 中这样的数包括 1、2、9、10 至 32、39 和 40,共 28 个,他们的和是574。
请问,在1到n中,所有这样的数的和是多少?
输入描述
输入格式:
输入一行包含两个整数 n(1≤n≤ 104)
输出描述
输出一行,包含一个整数,表示满足条件的数的和。

#include <bits/stdc++.h>
using namespace std;

bool f(int x)
{
    while (x)
    {
        int y = x % 10; //个位数
        if (y == 2 || y == 0 || y == 1 || y == 9)return true;
        x /= 10; //缩小十倍,向下取整
    }
    return false;
}

int main()
{
    int n; cin >> n;
    int ans = 0;
    for (int i = 1; i <= n; ++i)
    {
        if (f(i))ans += i;
    }
    cout << ans << '\n';
    return 0;
}

(三、找到最多的数)

用户登录

题目描述
小明对数位中含有 2、0、1、9的数字很感兴趣(不包括前导 0),在1到40 中这样的数包括 1、2、9、10 至 32、39 和 40,共 28 个,他们的和是574。
请问,在1到n 中,所有这样的数的和是多少?
输入描述
输入格式:
输入一行包含两个整数n(1≤n≤ 104)

#include <bits/stdc++.h>
using namespace std;

bool f(int x)
{
    while (x)
    {
        int y = x % 10;
        if (y == 2 || y == 0 || y == 1 || y == 9)return true;
        x /= 10;
    }
    return false;
}

int main()
{
    int n; cin >> n;
    int ans = 0;
    for (int i = 1; i <= n; ++i)
    {
        if (f(i))ans += i;
    }
    cout << ans << '\n';
    return 0;
}

(四、小蓝的漆房)

用户登录

问题描述
小蓝是一位有名的漆匠,他的朋友小桥有一个漆房,里面有一条长长的走廊,走廊两旁有许多相邻的房子,每间房子最初被涂上了一种颜色。
小桥来找小蓝,想让他把整个走廊都涂成同一个颜色。小蓝告诉小桥,他每天只能涂一段长度为ん的区间。对于每个区间,他可以选择将其中的房子重新涂上任何一种颜色,或者保持原来的颜色不变
小桥想知道小蓝至少要涂几天,才能让整个走廊变得美丽。
请帮助小桥解决这个问题。
输入格式
第一行包含一个整数t(1< 100),表示测试用例的数量.
每个测试用例的第一行包含两个整数 n 和 k(1 ≤ k≤n< 104),第二行包含几 个整数 a1,a2,···,an(1 < ai< 60),分别表示每个房子最初的颜色。
保证所有测试用例中 n 的总和不超过 10000。

首先,我们可以枚举整个走廊需要被涂上的颜色。因为颜色的种类数最多只有 60,所以我们可以尝试枚举每一种颜色。

对于每种颜色,我们需要计算涂上它需要的最少天数。我们可以从左到右遍历每个房子,如果该房子的颜色不是当前正在涂的颜色,那么我们就从该房子开始,向右涂 k 个房子,直到将该区间都涂上目标颜色。具体来说,我们可以用另一个数组 b 来记录当前的涂漆情况,每次枚举涂漆区间时,都将 b 数组中对应的区间涂成目标颜色。

在涂漆过程中,我们需要记录涂漆的天数 cnt,每当涂漆颜色发生变化时,我们就需要增加一天。最终,我们可以对所有颜色涂上所需的天数取最小值,该最小值即为答案。

综上所述,解题步骤如下:

  1. 枚举整个走廊需要被涂上的颜色;
  2. 对于每种颜色,计算涂上它需要的最少天数:从左到右遍历每个房子,如果该房子的颜色不是当前正在涂的颜色,那么就从该房子开始,向右涂 k 个房子,直到将区间涂上目标颜色,同时记录涂漆天数 cnt,每当涂漆颜色发生变化时,增加一天;
  3. 将所有颜色涂上所需的天数取最小值,即为答案。
#include <bits/stdc++.h>

void solve(const int &Case) {
    int n, k;
    std::cin >> n >> k;
    std::vector<int> a(n);
    for (auto &x: a)std::cin >> x; //range-for-each
    int ans = n + 1; // 初始化答案ans为一个大于n的值,以便后续取最小值  
    for (int c = 1; c <= 60; c++) {//枚举最终颜色
        int ret = 0;//存放当前最终颜色
        for (int i = 0; i < n; i++) {
            if (a[i] != c) { 
            // 如果出现一个与最终颜色不同的位置, 则贪心地选择该位置为染色的起点
                //i,i + 1,i + 2,...,i +k - 1 都会被立刻染成最终颜色
                ret++;
                i = i + k - 1;
            }
        }
        ans = std::min(ans, ret);
    }
    std::cout << ans << '\n';
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    int T = 1;
    std::cin >> T;
    for (int i = 1; i <= T; i++)solve(i);
    return 0;
}

(五、小蓝和小桥的挑战)

用户登录

解题思路

这道题的解题思路比较简单,具体步骤如下:

  1. 读入测试数据的数量 t,对于每组测试数据,读入物品数量 n 和物品价值 1,2,⋯,a1​,a2​,⋯,an​。

  2. 统计价值为 0 的物品个数 z,并计算物品的价值和 sum。如果序列中存在 00,则我们需要对所有的 0 进行一次操作,使得其变为 1,这样才能保证价值积不为 0。因此,我们至少需要进行 z 次操作。

  3. 对于经过操作后的序列,统计其所有元素的和 sum。如果sum≠0,则此时的序列已经满足题目要求,输出操作次数 z 即可。

  4. 如果 sum=0,则我们需要对任意一个 ai​>0,并对其进行一次操作,使得 ai​++,因为只要序列中存在正整数,我们就可以利用这些正整数来使得序列的价值积不为 00。如果序列中不存在 ai​>0,则我们需要对任意一个元素进行一次操作,使得序列中至少有一个非 0 的元素,然后再按照上述方法进行操作。因此,此时的操作次数为 z+1。

#define  _CRT_SECURE_NO_WARNINGS 1
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;
int a[N], t, n;
int main()
{
	cin >> t;
	while (t--)
	{
		cin >> n;
		int sum = 0, z = 0;
		for (int i = 1; i <= n; ++i)
		{
			cin >> a[i],sum += a[i];
			if (!a[i])++z;//如果a[i] == 0,执行一次操作
		}
		sum += z;//输入的数 + 执行加一后的次数
		if (sum == 0)//如果和为0
		cout << z + 1 << '\n';
		else cout << z << '\n';
	}
	return 0;
}

 乘积和加法的和都不为0
 如果只考虑乘积不为0
 如果乘积为0,则说明存在零(zero)元素
 此时的答案一定是所有零(zero)元素都加一
 如果只考虑加法为0, 那么随便选择一个数加一
 回到原问题, 同时考虑乘法和加法
 1.乘积为0, 且加法也为0
 此时将所有零(zero)元素加一即可
 2.乘积为0, 加法不为0
 2.1.乘积为0, 加法不等于零(zero)元素的个数的相反数
 此时将所有零(zero)元素加一即可
 2.2.乘积为0, 加法等于零(zero)元素的个数的相反数
 此时将所有0元素加一后, 再选择一个数加一
 3.乘积不为0,加法为0
 此时将某个正数加一即可
 4.乘积不为0,加法也不为0
 不动

#include <bits/stdc++.h>
void solve(const int &case)
{
  int n;
  std::cin >> n;
  int zeroCount = 0, sum = 0; // zeroCount 记录0的个数,sum 记录所有整数的和  
    for (int i = 0; i < n; i++) {  
        int x;  
        std::cin >> x; // 输入一个整数  
        if (x == 0) zeroCount++; // 如果输入的整数是0,zeroCount自增  
        sum += x; // 将输入的整数累加到sum上  
    }  
    // 如果存在0,则至少需要zeroCount次操作将0变为非0数(每次操作可以将一个0变成任意非0数)  
    // 如果不存在0,但所有数的和为0,则至少需要1次操作(将所有数同时加上一个非0数)  
    // 如果既不存在0,所有数的和也不为0,则不需要操作  
    if (zeroCount > 0) {  
        std::cout << zeroCount << '\n'; // 输出将0变成非0数的最少操作次数  
    } else if (sum == 0) {  
        std::cout << 1 << '\n'; // 输出将所有数和变成非0数的最少操作次数(1次)  
    } else {  
        std::cout << 0 << '\n'; // 不需要操作,直接输出0  
    }
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);// 取消读入输出的同步流, 取消后不能使用 scanf和printf
    int T = 1;
    std::cin >> T;
    for (int i = 1; i <= T; i++)solve(i);
    return 0;
}

今天就先到这了!!!

看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注!

你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1477990.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【力扣hot100】刷题笔记Day17

前言 今天竟然不用开组会&#xff01;天大的好消息&#xff0c;安心刷题了 46. 全排列 - 力扣&#xff08;LeetCode&#xff09; 回溯&#xff08;排列&#xff09; class Solution:def permute(self, nums: List[int]) -> List[List[int]]:# 回溯def backtrack():if len(…

一、前端开发

#视频链接&#xff1a;https://www.bilibili.com/video/BV1rT4y1v7uQ?p1&vd_source1717654b9cbbc6a773c2092070686a95 前端开发 前端开发1、快速开发网站2、浏览器能识别的标签2.1 编码&#xff08;head&#xff09;2.2 title(head)2.3 标题2.4 div和span练习题2.5 超链接…

如何做代币分析:以 USDT 币为例

作者&#xff1a;lesleyfootprint.network 编译&#xff1a;cicifootprint.network 数据源&#xff1a;USDT Token Dashboard &#xff08;仅包括以太坊数据&#xff09; 在加密货币和数字资产领域&#xff0c;代币分析起着至关重要的作用。代币分析指的是深入研究与代币相关…

prometheus监控带安全认证的elasticsearch

1.下载elasticsearch_exporter wget 下载二进制包并解压、运行&#xff1a; wget https://github.com/prometheus-community/elasticsearch_exporter/releases/download/v1.3.0/elasticsearch_exporter-1.3.0.linux-amd64.tar.gz tar -xvf elasticsearch_exporter-1.3.0.lin…

imazing是啥 ?iMazing 3.0.0.3中文版会有哪些新功能?

imazing是啥 imazing是管理iOS设备的软件 iMazing 是一款用于管理iOS设备的软件。它支持在Windows和Mac电脑上对基于iOS系统的设备进行数据传输、备份和管理。用户可以通过这款软件传输和备份包括照片、音乐、铃声、视频、电子书及通讯录等多种信息。不仅限于iPhone、iPad或iP…

1、docker 基础命令

1、docker 运行镜像 docker run image tag 2、创建dockerfile&#xff08;构建容器的相关命令&#xff09; vim DockerFile 3、docker 构建容器镜像 docker build -t <image_name> . 4、docker 分层 5、查看镜像 docker images 6、docker 执行 docker run --name &…

言语理解与表达-郭熙-02

1、上节回顾 1.1 转折关系 1.2 因果关系 1.3 主题词 2、本课目录 3、必要条件关系 3.1 题目 4、对策类 4.1 题目 5、反面论证 提对策 题目 6、必要关系总结 7、程度词 题目 易错&#xff1a; 8、并列关系 题目 易错&#xff1a;

Java面试题之并发

并发 1.并发编程的优缺点&#xff1f;2.并发编程三要素&#xff1f;3.什么叫指令重排&#xff1f;4.如何避免指令重排&#xff1f;5.并发&#xff1f;并行&#xff1f;串行&#xff1f;6.线程和进程的概念和区别&#xff1f;7.什么是上下文切换&#xff1f;8.守护线程和用户线程…

lv20 QT对话框3

1 内置对话框 标准对话框样式 内置对话框基类 QColorDialog, QErrorMessage QFileDialog QFontDialog QInputDialog QMessageBox QProgressDialogQDialog Class帮助文档 示例&#xff1a;各按钮激发对话框实现基类提供的各效果 第一步&#xff1a;实现组件布局&…

dolphinscheduler集群部署教程

文章目录 前言一、架构规划二、配置集群免密登录1. 配置root用户集群免密登录1.1 hadoop101节点操作1.2 hadoop102节点操作1.3 hadoop103节点操作 2. 创建用户2.1 hadoop101节点操作2.2 hadoop102节点操作2.3 hadoop103节点操作 三、安装准备1. 安装条件2. 安装jdk3. 安装MySQL…

FreeRTOS 信号量

目录 一、信号量的概念 二、二值信号量 1、二值信号量的定义 2、二值信号量的作用 3、二值信号量的操作 4、二值信号量操作实验 5、二值信号量会导致优先级翻转问题 三、互斥信号量 1、互斥信号量的引入 2、注意&#xff1a;互斥信号量不能用于中断服务函数中&#xf…

kali linux通过aircrack-ng命令破解wifi密码

相关阅读&#xff1a;如何破解攻击WiFi 百度安全验证https://baijiahao.baidu.com/s?id1764248756021219497&wfrspider&forpc上面2篇文章写得都很不错 一、前期准备工作 1、将无线网卡挂载到Kali上 ​ 将无线网卡插到电脑上&#xff0c;如果弹出检测到新的USB设备&…

戏说c语言: 阶段性总结二

前言 师弟&#xff1a;“师兄&#xff0c;我终于和我喜欢的女生在一起了。感谢师兄呀。” 我&#xff1a;“恭喜啊&#xff0c;师弟&#xff01;” 师弟&#xff1a;“这要全靠这段学习c的缘分了啊&#xff0c;两个人没事交流c语言&#xff0c;一起去上课&#xff0c;共同成长…

vue3使用echarts绘制地图

vue3使用echarts绘制地图 安装echarts npm install echarts下载地图的json数据【我这里是把json数据单独粘出来然后新建了一个文件china.json】 下载中国及各个省份的地图数据引入 import chinaJson from ./china.json绘制地图 <template><div ref"myChart&q…

申请Sectigo证书

Sectigo&#xff08;前身为Comodo CA&#xff09;&#xff0c;是目前全球最优质的网络安全服务供应商之一。该证书颁发机构主要是为各个企业的网络数据安全传输提供解决方案以及用户数据安全。 其特点也非常鲜明&#xff0c;极具性价比&#xff0c;深受中小型企业的欢迎。其证…

企业有了ERP,为什么还要上BI?

在我们以往和企业的沟通过程中&#xff0c;我们发现还是有相当多的一部分企业对于商业智能 BI 了解不多&#xff0c;或者对商业智能 BI 的理解仅停留在花花绿绿的可视化页面上&#xff0c;要么就是提出以下类似问题&#xff1a; 财务部门&#xff1a;BI 的财务分析指标也就是三…

可靠性技术之链路聚合(LACP模式)

LACP模式下&#xff0c;两端设备所选择的活动接口数目必须保持一致&#xff0c;否则链路聚合组就无法建立。此时可以使其中一端成为主动端&#xff0c;另一端(被动端)根据主动端选择活动接口。通过系统LACP优先级确定主动端&#xff0c;值越小优先级越高。 在未配置链路聚合时&…

PDF Expert for Mac v3.9.2中文激活版下载

PDF Expert for Mac是一款易于使用的 PDF 编辑器和注释器&#xff0c;专为 Mac 设备设计。它允许用户轻松查看、编辑、签名、注释和共享 PDF。该软件使用户能够向他们的 PDF 添加文本、图像、链接和形状&#xff0c;突出显示和标记文本&#xff0c;填写表格以及签署数字文档。它…

02|JVM内存模型

1. JVM整体结构及内存模型 1.1 类装载子系统 负责加载字节码文件并将其转换为可以执行的Java类。类加载器子系统包括三个主要的类加载器&#xff1a;Bootstrap ClassLoader&#xff08;引导类加载器&#xff09;、Extension ClassLoader&#xff08;扩展类加载器&#xff09;和…

输入一个整数n,输出这个整数的二进制的0和1的个数

输入一个整数n&#xff0c;输出这个整数的二进制的0和1的个数:除二取余法 代码&#xff1a; #include <cstdio> int main() {int n;scanf_s("%d", &n);int arr[2] { 0 };while (n) {int yu n % 2;arr[yu];n n / 2;}printf("0的个数是&#xff1a…