蓝桥杯c++算法学习【1】之枚举与模拟(卡片、回文日期、赢球票、既约分数:::非常典型的比刷例题!!!)

别忘了请点个赞+收藏+关注支持一下博主喵!!!

关注博主,更多蓝桥杯nice题目静待更新:)

枚举与模拟
一、卡片:
【问题描述】

        小蓝有很多数字卡片,每张卡片上都是一个数字(0到9)。 

        小蓝准备用这些卡片来拼一些数,他想从1开始拼出正整数,每拼一个,就保存起来,卡片就 不能用来拼其他数。

        想知道自己能从1拼到多少。

        例如,当小蓝有30张卡片,其中0到9各3张,则小蓝可以拼出1到10,但是拼 11时卡片1已经只有一张了,不够拼出11。

         现在小蓝手里有0到9的卡片各2021张,共20210张,请问小蓝可以从1拼到 多少? 提示:建议使用计算机编程解决问题。

【答案提交】

         这是一道结果填空题,你只需要算出结果后提交即可。本题的结果作为一个整数,在 提交答案时只填写这个整数,填写多余的内容将无法得分

解析:

  本题思路较为简单,可直接从数字1开始往后枚举,枚举的同时检查剩下的卡片能不能拼出当前枚举到的数字即可。

         定义cnt[i] 表示刻有数字i的卡片张数。那么按照题目的意思,初始化cnt[0∼9]=2021, 参考代码如下。

int cnt[10];
for(int i = 0 ; i <= 9 ; i++) cnt[i] = 2021;

若我们将步骤拆分为两步,则可分为枚举、检查。枚举没什么问题,写个循环即可,但 该怎么检查呢? 

         首先就需要把一个数在十进制下的每一位数字求出来。怎么求呢? 可以将该数对 10 取 模,这样就得到了个位上的数字;再除以10,这样原本十位上的数字就跑到了个位上;然后 再对10取模……反复这个过程,就可以得到这个数在十进制下所有数位上的数字了。

得到数位上的所有数字后再看看这些数字对应的卡片够不够,不够的话就说明这个数拼 不了,就停止枚举,这样答案就为上一个枚举的数。

bool check(int x) { // x 表示当前枚举的数while (x) {int b = x % 10; // 获取十进制下的每个数位if (cnt[b] > 0) cnt[b]--; // 这个数位对应的卡片个数 -1else return false; // 如果卡片不够了,则无法拼凑出该数x /= 10; // 将十位变为个位}return true;
}

至此,检查的模块就完成了。不过我们还可以进行一点小小的优化。

        我们的枚举是从1开始的,如果分别看枚举数的个位、十位……上的数字,那么会得到 如下的内容。

 显然,个、十、百、千、万……每一数位的变化都是有周期性的。每个周期中各个数字出 现的次数都是相同的,且每一数位都是从1开始变化的。因此,刻有数字1的卡片一定会被 最早使用完,我们只需要对该卡片的张数作判断就好,具体代码可见参考代码第4∼14行。 

#include <bits/stdc++.h>
using namespace std;int cnt[10];bool check(int x) { // x 表示当前枚举的数while (x) {int b = x % 10; // 获取十进制下的每个数位if (b == 1) {if (cnt[1] == 0) return false;cnt[1]--;}x /= 10; // 将十位变为个位}return true;
}signed main() {for (int i = 0; i <= 9; i++) cnt[i] = 2021;for (int i = 1;; i++) {if (!check(i)) return cout << i - 1 << '\n', 0;}return 0;
}

最终答案为3181。

二、回文日期:
【问题描述】

         2020年春节期间,有一个特殊的日期引起了大家的注意:2020年2月2日。因为 如果将这个日期按“yyyymmdd”的格式写成一个8位数是20200202,恰好是一个回文数。我们称这样的日期是回文日期。

         有人表示20200202是“千年一遇”的特殊日子。对此小明很不认同,因为不到2年 之后就是下一个回文日期:20211202即2021年12月2日。

        也有人表示20200202并不仅仅是一个回文日期,还是一个ABABBABA型的回文 日期。对此小明也不认同,因为大约100年后就能遇到下一个ABABBABA型的回文日 期:21211212即2121年12月12日。算不上“千年一遇”,顶多算“千年两遇”。

        给定一个8位数的日期,请你计算该日期之后下一个回文日期和下一个ABAB BABA型的回文日期各是哪一天。

【输入格式】

         输入包含一个八位整数N,表示日期。 对于所有评测用例,10000101⩽N⩽89991231,保证N是一个合法日期的8位数表示。

【输出格式】

         输出两行,每行1个八位数。第一行表示下一个回文日期,第二行表示下一个ABAB BABA型的回文日期。

【样例输入】 

        20200202 

【样例输出】

        20211202 21211212

【答案提交】

         这是一道结果填空题,你只需要算出结果后提交即可。本题的结果作为一个整数,在 提交答案时只填写这个整数,填写多余的内容将无法得分。

解析:

根据题意,我们可以将题目拆解为如何判断回文和如何枚举日期两个部分来解决。

        1. 如何判断回文

        对于一个8位数的整型日期,可以通过除法和取余运算来获取它的每一位数字。比如 

若整数date 的值为20050511,它从高到低的每一数位上的数可以通过下列方法得到。
• data / 10000000 = 2;
• data / 1000000 % 10 = 0;
• data / 100000 % 10 = 0;
• data / 10000 % 10 = 5;
• data / 1000 % 10 = 0;
• data / 100 % 10 = 5;
• data / 10 % 10 = 1;
• data % 10 = 1。

对于本题,若用a[1]、a[2]、a[3]、a[4]、a[5]、a[6]、a[7]、a[8] 分别存储每一位,则一个 回文日期须满足:         

一个ABABBABA 型回文日期须满足以下条件。

a[1] = a[3] = a[6] = a[8];a[2] = a[4] = a[5] = a[7].                                                         

        对于一个日期字符串,可以直接通过下标来获取它的每一位数字。例如,string date = “20050511”,它从高到低的每一位分别可以通过data[0],data[1],...,data[7] 得到。判断回文日期及ABABBABA型回文日期的方式和上述方法类似。

        不难看出,字符串获取日期的每一位数字是要比整型简单的,所以在判断回文日期及 ABABBABA 型回文日期时可以将整型转换为字符串来操作,如参考代码所示。

#include <bits/stdc++.h>
using namespace std;int date = 20050511;
string s = to_string(date); // 将整型转换为字符串, s = "20050511"// 判断回文日期
bool check1(int date) {string s = to_string(date);if (s[0] == s[7] && s[1] == s[6] && s[2] == s[5] && s[3] == s[4])return true;return false;
}// 判断 ABABBABA 型回文日期
bool check2(int date) {string s = to_string(date);if (s[0] == s[2] && s[0] == s[5] && s[0] == s[7] && s[1] == s[3] && s[1] == s[4] && s[1] == s[6])return true;return false;
}

 2. 如何枚举日期

        对于一个整型日期,可以用最简单的方式枚举,即令该日期不断+1,直到出现满足ABAB BABA 型的回文日期。

         但这样存在一个问题:会枚举出许多不合法的日期(如20209999)。为此,我们需要对 日期进行合法性判断:设y,m,d分别表示年、月、日,month[i]表示第i个月的天数,那么当m12或dmonth[m]时日期不合法,反之日期合法,如参考代码所示。

#include <iostream>
#include <string>
using namespace std;int month[13] = {-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};bool check(int date) {string s = to_string(date);//stoi->将字符串转为整型int y = stoi(s.substr(0, 4)), m = stoi(s.substr(4, 2)), d = stoi(s.substr(6, 2));if (y % 400 == 0 || (y % 4 == 0 && y % 100 != 0)) month[2] = 29;else month[2] = 28;if (m < 1 || m > 12 || d < 1 || d > month[m]) return false;return true;
}int main() {int date = 20050511;for (int i = date + 1;; i++) {if (!check(i)) continue;// 找到下一个有效日期后,可以在这里进行进一步处理// 例如,检查是否是回文日期或 ABABBABA 型回文日期cout << "Next valid date: " << i << endl;break;}return 0;
}

不过这样的枚举量是相当大的,要在比赛中完成本题要求的所有测试数据不太现实。

        那么,还有什么枚举方法呢?

        可以直接枚举合法日期。枚举合法日期只需模拟日期的变化规律即可,对应参考代码如 下所示。

#include <iostream>
using namespace std;int month[13] = {-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};int main() {int date = 20050511;int y = date / 10000, m = date / 100 % 100, d = date % 100;for (int i = y;; i++) {if (i % 400 == 0 || (i % 100 != 0 && i % 4 == 0)) month[2] = 29; // 闰年2月有29天else month[2] = 28;int j = (i == y) ? m : 1; // 如果是i = y,则月份从m开始枚举,否则从1开始枚举for (; j <= 12; j++) {int k = (i == y && j == m) ? d : 1; // 如果i = y并且j = m,则日从d开始枚举,否则从1开始枚举for (; k <= month[j]; k++) {int new_date = i * 10000 + j * 100 + k;// 在这里可以进行进一步处理,例如检查是否是回文日期或ABABBABA型回文日期cout << "Next valid date: " << new_date << endl;return 0; // 找到第一个有效日期后退出程序}}}return 0;
}

综上 :

枚举合法日期:

#include <bits/stdc++.h>
using namespace std;int month[13] = {-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int date, ans1, ans2;// 判断日期是否为回文
bool check1(int date) {string s = to_string(date);if (s[0] == s[7] && s[1] == s[6] && s[2] == s[5] && s[3] == s[4])return true;return false;
}// 判断日期是否满足 ABABBABA 型回文
bool check2(int date) {string s = to_string(date);if (s[0] == s[2] && s[0] == s[5] && s[0] == s[7] && s[1] == s[3] && s[1] == s[4] && s[1] == s[6])return true;return false;
}signed main() {cin >> date;int y = date / 10000, m = date / 100 % 100, d = date % 100;for (int i = y;; i++) {if (i % 400 == 0 || (i % 100 != 0 && i % 4 == 0))month[2] = 29;elsemonth[2] = 28;int j = (i == y) ? m : 1;for (; j <= 12; j++) {int k = (i == y && j == m) ? d + 1 : 1;for (; k <= month[j]; k++) {int new_date = i * 10000 + j * 100 + k;if (check1(new_date) && ans1 == 0)ans1 = new_date;if (check2(new_date)) {cout << ans1 << '\n' << new_date << '\n';return 0; // 当找到了 ABABBABA 型回文日期时,结束程序}}}}return 0;
}
枚举年份:
#include <bits/stdc++.h>
using namespace std;// month[1~12]分别记录1~12月每月的天数
int date, month[13] = {-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};// 判断日期是否合法
string check(int date) {string s = to_string(date), t = to_string(date); // 将整型转换为字符串reverse(t.begin(), t.end()); // 翻转s += t; // 将s翻转后再与s拼接,拼接后的字符串一定会是个回文串int y = stoi(s.substr(0, 4)), m = stoi(s.substr(4, 2)), d = stoi(s.substr(6, 2));if (y % 400 == 0 || (y % 4 == 0 && y % 100 != 0)) month[2] = 29;else month[2] = 28;if (m < 1 || m > 12 || d < 1 || d > month[m]) return "-1";return s;
}// 判断日期是否是ABABBABA型回文
string check2(int date) {string s = to_string(date), t = to_string(date);reverse(t.begin(), t.end()); // 翻转s += t;if (s[0] == s[2] && s[0] == s[5] && s[0] == s[7] && s[1] == s[3] && s[1] == s[4] && s[1] == s[6]) return s;return "-1";
}signed main() {cin >> date;string ans1 = "";for (int i = date / 10000;; i++) {// 注意:date(输入的日期)不能作为答案if (check(i) == "-1" || check(i) == to_string(date)) continue;if (ans1 == "") ans1 = check(i);if (check2(i) != "-1") {cout << ans1 << '\n' << check2(i) << '\n';return 0;}}return 0;
}

以上就是这次博客的内容了

别忘了请点个赞+收藏+关注支持一下博主喵!!!

关注博主,更多蓝桥杯nice题目静待更新:)

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

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

相关文章

html页面中的内容替换,或改变某些字的颜色

1. html页面中的内容替换,或改变某些字的颜色 前端使用innnerHtml显示返回值+innerHtml文字显示两种不同的颜色(两部分显示颜色不一样) 1.1. html字符串改变某些字的颜色 需求:要文本框的字体部分改变颜色、大小、换行等功能。在了解需求后,文本框input发现完全满足不了现需…

Linux——简单认识vim、gcc以及make/Makefile

前言&#xff1a;大佬写博客给别人看&#xff0c;菜鸟写博客给自己看&#xff0c;我是菜鸟。 1、vim操作&#xff1a; 默认打开vim时&#xff0c;vim处于命令模式。(在其他模式中&#xff0c;Esc就能够返回命令模式) 常用的命令有&#xff1a; n gg&#xff1a;跳转到n行&…

C++基础(12.红黑树实现)

目录 红黑树的概念&#xff1a; 红黑树规则&#xff1a; 红黑树如何确保最长路径不超过最短路径的2倍的&#xff1f; 红黑树的效率&#xff1a; 红黑树的插入: 红黑树树插入⼀个值的大概过程: 情况1&#xff1a;变色 情况2&#xff1a;单旋变色&#xff1a; 情况3&…

Spark 的容错机制:保障数据处理的稳定性与高效性

Spark 的介绍与搭建&#xff1a;从理论到实践_spark环境搭建-CSDN博客 Spark 的Standalone集群环境安装与测试-CSDN博客 PySpark 本地开发环境搭建与实践-CSDN博客 Spark 程序开发与提交&#xff1a;本地与集群模式全解析-CSDN博客 Spark on YARN&#xff1a;Spark集群模式…

Linux内核编程(二十)RTC子系统一驱动rx8010

本文目录 一、基础知识点1.什么是RTC&#xff1f;2. RTC方案3. 电路原理图 二、RTC芯片&#xff08;RX8010&#xff09;移植三、关于时间的一些命令四、应用层使用1. 使用RTC驱动2. 使用time.h库&#xff08;额外知识点&#xff09; 一、基础知识点 1.什么是RTC&#xff1f; R…

GESP4级考试语法知识(贪心算法(一))

海盗船代码&#xff1a; #include<iostream> #include<algorithm> using namespace std; int data[21]; int main() {int n;cin>>n;for(int i0;i<n;i)cin>>data[i];sort(data,datan);int temp0,sum0;for(int i0;i<n;i){tempdata[i];if(temp>…

036 RabbitMQ消息确认 死信队列 延时队列

文章目录 生产者确认模式application.propertiesMessageController.javaMessageConfirmRallback.java 生产者回退模式application.propertiesMessageConfirmRallback.javaMessageController.java 消费者手动确认application.propertiesConsumerAckQueueListener.java 死信队列延…

Unity 插件 - Project窗口资源大小显示

Unity 插件 - Project窗口资源大小显示 &#x1f354;功能&#x1f32d;安装 &#x1f354;功能 &#x1f4a1;.显示Project Assets 和Packages下所有文件的大小&#xff08;右侧显示&#xff09; &#x1f4a1;.统计选中文件夹及其子文件夹下所有文件的大小并显示&#xff08…

Maven 中央仓库地址 mvnrepository.com

下载一些 jar 包驱动&#xff0c;不需用去官网下了&#xff0c;直接去 Maven 中央仓库&#xff0c;高效、简单 Maven 中央仓库地址 https://mvnrepository.com/open-source 我们下期见&#xff0c;拜拜&#xff01;

制作自己的刷题小题库,提高刷题效率

日常刷题 乱序/背题多种模式 组队刷题 查看小组的刷题统计 在线考试 创建考试多人同时答题 ----这是一条分割线----- 土著刷题&#xff0c;是一款可以导入题库的在线刷题学习小&#x1f34a;序&#xff0c;提供一套以【搭建题库-组建小组-刷题练习-在线考试】为中心的完整服务…

WPF在MVVM模式下怎么实现导航功能

在mvvm的模式下wpf通过frame实现页面跳转_哔哩哔哩_bilibili 视频讲解同步可观看 如下图&#xff0c;我们要实现点击左侧的菜单&#xff0c;在右侧展示不同的页面 实现代码如下&#xff1a; 一、如何从主窗体跳转到页面。 1、在mainwindow.xaml的菜单栏代码里加入如下代码 …

VSCode中python插件安装后无法调试

问题 VSCode中python插件安装后无法调试&#xff0c;如下&#xff0c;点击调试&#xff0c;VScode中不报错&#xff0c;也没有调试 解决方法 1、查看配置 打开所在路径 2、拷贝 将整个文件夹拷贝到vscode默认路径下 3、问题解决 再次调试&#xff0c;可以正常使用了…

光模块基础知识

1. 光模块的封装 光模块是光收发模块的简称&#xff0c;主要根据不同的外型来区分&#xff0c;而在同一外型中&#xff0c;又有着多种规格&#xff1b;在数据通信领域&#xff0c;最常见的光模块&#xff08;根据外型区分&#xff09;分别是SFF、GBIC、SFP、和XFP、QSFP 、XEN…

【GPTs】MJ Prompt Creator:轻松生成创意Midjourney提示词

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | GPTs应用实例 文章目录 &#x1f4af;GPTs指令&#x1f4af;前言&#x1f4af;MJ Prompt Creator主要功能适用场景优点缺点 &#x1f4af; 小结 &#x1f4af;GPTs指令 中文翻译&#xff1a; 任务说明 您是一款为幻灯片工…

uniapp路由与页面跳转详解:API调用与Navigator组件实战

UniApp路由与页面跳转详解&#xff1a;API调用与Navigator组件实战 路由 uniapp页面路由为框架统一管理&#xff0c;开发者需要在page.json里面配置每个路由页面的路径及页面样式。 路由跳转 uniapp有两种页面路由跳转方式&#xff0c;调用API跳转和navigator组件跳转。 调…

机器学习 笔记

特征值提取 字典 from sklearn.extaction import DictVectorizer mDictVectorizer(sparseFalse)#sparse是否转换成三元组形式 data[], #传入字典数据 data1model.fit_transform(data) #使用API 英文特征值提取 from sklearn.feature_extraction.text import CountVe…

【智谱开放平台-注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

如何搭建自动化测试框架

软件测试资料领取&#xff1a;[内部资源] 想拿年薪40W的软件测试人员&#xff0c;这份资料必须领取~ 软件测试面试刷题工具&#xff1a;软件测试面试刷题【800道面试题答案免费刷】 关于测试框架的好处&#xff0c;比如快速回归提高测试效率&#xff0c;提高测试覆盖率等这里…

学Linux的第八天

目录 管理进程 概念 程序、进程、线程 进程分类 查看进程 ps命令 unix 风格 bsd风格 GNU风格 top命令 格式 统计信息区 进程信息区&#xff1a;显示了每个进程的运行状态 kill命令 作用 格式 管理进程 概念 程序、进程、线程 程序&#xff1a; 二进制文件&…

使用Matlab建立决策树

综述 除了神经网络模型以外&#xff0c;树模型及基于树的集成学习模型是较为常用的效果较好的预测模型。我们以下先构建一个决策树模型。 决策树算法的优点如下&#xff1a;1、 决策树易于理解和实现&#xff0c;用户在学习过程中不需要了解过多的背景知识&#xff0c;其能够…