枚举算法入门
在某个可能的解的集合中,按某个顺序依次检索元素,用题目给定的条件进行校验和计算。是否存在,找到第一个,全部都,全部都不。 原数组中是否存在子数组?(元素无需连续,但需保持相对顺序一致) templata<typename T>bool subMatch(const T&arr,const T&target){ size_t idx=0; for (auto &elem : arr) { if(elem==target[idx]) { if(++idx == target.size()) return true; } } return false;} 寻找第K小的素数? for(int idx=1;;idx++){ if(isPrime(idx)) cnt++; if(cnt==k) { cout<<idx; break; }} 枚举的优化:裁剪枚举集判断...
好数
一个整数如果按从低位到高位的顺序,奇数位(个位、百位、万位 · · · )上的数字是奇数,偶数位(十位、千位、十万位 · · · )上的数字是偶数,我们就称之为“好数”。给定一个正整数 N,请计算从 1 到 N 一共有多少个好数。 我的思路就是利用 while(x){ int dight = x % 10; // do something x /=10;} 取它的每一位判断,但我怎么可以确定每一位是对应奇数位还是偶数位了?我无法确定,于是我就想到一种简单粗暴的方式,把从低位到高位的每一位取出来然后存放在数组中,用两个循环分别遍历数组的奇数位和偶数位,判断每一位是不是符合要求。于是就有了下面的代码。 #include<iostream>#include<vector>using namespace std;bool IsHaoShu(int N){ vector<int> arr1; int n; while(N){ n=N%10; arr1.push_back(n); N/=...
卡片
小蓝有很多数字卡片,每张卡片上标有 0到9 中的一个数字。他想用这些卡片从 1 开始拼出连续的正整数,每拼一个数,就把用到的卡片保存起来,之后不能再用这些卡片拼其他数。例如,如果小蓝手里有 30 张卡片,每个数字 0到9 各 3 张,他可以拼出 1到10,但是拼 11 时,数字 1 的卡片已经不够用了。现在,小蓝手里有每个数字 0到9 的卡片各 2021 张(总共 20210 张),问他能够从 1 拼到的最大连续整数是多少?这道题的思路也很简单,咱们准备一个十个空间大小的数组vec[10],都存储2021,代表0~9的卡片都有2021张,遍历从1开始的数,我们将它逐位分解,对于分解出的每一位x,vec[x]–,直到某个数分解出的某位i,vec[i]=0时,说明没有卡片去给它组成这个数了,那么答案就是这个数的上一个数。 #include<iostream>#include<vector>using namespace std;vector<int> vec(10,2021);int work(){ for(int i=1...
小球反弹
有一长方形,长为 343720 单位长度,宽为 233333 单位长度。 在其内部左上角顶点有一小球 (无视其体积),其初速度如图所示且保持运动速率不变,分解到长宽两个方向上的速率之比为 dx:dy=15:17。 小球碰到长方形的边框时会发生反弹,每次反弹的入射角与反射角相等,因此小球会改变方向且保持速率不变(如果小球刚好射向角落,则按入射方向原路返回)。从小球出发到其第一次回到左上角顶点这段时间里,小球运动的路程为多少单位长度?答案四舍五入保留两位小数。![[Pasted image 20260119121851.png]]可以把小球每次反弹都投影到一个镜像世界里面假设lenth=343720,wide=233333![[未命名绘图.drawio.png]]我们可以观察到原点在镜像世界中的投影点满足x为2 * lenth的整数倍数,y为2 * wide的整数倍数。小球每时每刻沿直线运动在x和y轴上的分量都满足15:17。枚举t从1到正无穷,使得小球在t时刻的x和y运动分量满足到达原点所要求的条件。 #include<iostream>#...
日期统计
小蓝现在有一个长度为100的数组,数组中的每个元素的值都在0 到9 的范围之内。数组中的元素从左至右如下所示5 6 8 6 9 1 6 1 2 4 9 1 9 8 2 3 6 4 7 7 5 9 5 0 3 8 7 5 8 1 5 8 6 1 8 3 0 3 7 9 2 7 0 5 8 8 5 7 0 9 9 1 9 4 4 6 8 6 3 3 8 5 1 6 3 4 6 7 0 7 8 2 7 6 8 9 5 6 5 6 1 4 0 1 0 0 9 4 8 0 9 1 2 8 5 0 2 5 3 3现在他想要从这个数组中寻找一些满足以下条件的子序列:子序列的长度为8;这个子序列可以按照下标顺序组成一个yyyymmdd 格式的日期,并且要求这个日期是2023 年中的某一天的日期,例如20230902,20231223。yyyy 表示年份,mm 表示月份,dd 表示天数,当月份或者天数的长度只有一位时需要一个前导零补充。请你帮小蓝计算下按上述条件一共能找到多少个不同的2023 年的日期。对于相同的日期你只需要统计一次即可。 枚举2023年的每一天进行子序列的匹配 #include&...
神奇闹钟
小蓝发现了一个神奇的闹钟, 从纪元时间(1970 年 1月 1日 00: 00: 00)开始, 每经过 x 分钟, 这个闹钟便会触发一次闹铃 (纪元时间也会响铃). 这引起了小蓝的兴趣, 他想要好好研究下这个闹钟.对于给出的时间一个格式为 yyyy-MM-dd HH:mm:ss 的时间, 小蓝想要知道在这个时间点之前(包含这个时间点)最近的一次闹铃是什么时间?注意,你不必考虑时区问题。输入格式输入的第一行包含一个整数 T , 表示每次输入包含 T 组数据.接下来依次描述 T 组数据.每组数据一行。包含一个时间(格式为 yyyy-MM-dd HH:mm:ss)和一个整数 x ,其中 x表示闹铃时间间隔(单位为分钟).输出格式输出 T 行. 每行包含一个时间(格式为 yyyy-MM-dd HH:mm:ss),依次表示每组数据的答案。 首先把从1970年到输入时间之间的秒数long long res算出来,再计算出可以触发闹铃的次数n= (res / (x * 60)) ,从而计算出从1970年开始到最后一次闹铃之间的秒数res= (res / ...
特殊日期
记一个日期为 yy 年 mm 月 dd 日。统计从 2000 年 1 月 1 日(含)到 2000000 年 1 月 1 日(含),有多少个日期满足年份 yy 是月份 mm 的倍数,同时也是 dd 的倍数。当年份是 4 的倍数而不是 100 的倍数或者年份是 400 的倍数时,这一年是闰年,其他的年份都不是闰年。遍历每一年的每一个月的每一天。二月份天数最为特殊,闰年29,平年28我们可以先创建一个数组int MonthDay[12]={31,28,31,30,31,30,31,31,30,31,30,31}在遍历年的循环中设置一个flag=((i%4 == 0 && i%100!=0) || (i%400 == 0))更新MonthDay[1]=28+flag这样就解决二月份天数问题 #include<iostream>using namespace std;int main(){ int MonthDay[12]={31,28,31,30,31...
寻找2020
给定一个 n×n 的二维数组,数组中的每个元素都是 0 或 2。请你统计数组中连续的四个元素恰好组成 2020 的序列个数。连续序列的方向限定为以下 4 种: 水平向右:同一行中,从左到右连续 4 个元素 竖直向下:同一列中,从上到下连续 4 个元素 主对角线向下:左上到右下方向,连续 4 个元素 副对角线向下:右上到左下方向,连续 4 个元素 输入格式 第一行输入一个整数 n(4≤n≤1000),表示二维数组的行数和列数 接下来 n 行,每行输入一个长度为 n 的字符串,字符串仅由 0 和 2 组成 输出格式输出一个整数,表示满足条件的 2020 序列的总个数 这道题目刚开始我理解的意思时,一个序列的四个元素只能用一次,下一次寻找的序列的元素要是没有被选中过的,这种想法应该有很多不一样的答案。这道题的意思其实时找出所有可能不考虑是否构成序列的元素是否被用过。我们只需要遍历每一个元素,看它在这四种序列方向上是否可以构成一个2020序列。在遍历时可以简化枚举次数。比如一个n*n的二维数组,(i,j)处的数要构成横向的2020则必须要j+3<=n,同理要构成竖向...
幸运数
小蓝认为如果一个数含有偶数个数位,并且前面一半的数位之和等于后面 一半的数位之和,则这个数是他的幸运数字。例如2314是一个幸运数字,因为 它有4个数位,并且2+3=1+4。现在请你帮他计算从1至100000000之间 共有多少个不同的幸运数字? 这道题思路比较简单,一个数对10取对数然后向上取整可以得到它的位数,对于位数为偶数的数,按位枚举,前一半相加后一半相加。 #include<iostream>#include<cmath>using namespace std;bool IsLucky(int n){ int m=log10(n)+1,sum1=0,sum2=0,index=1; if(m%2!=0) return false; while(n) { int dight=n%10; if(index>m/2) sum2+=dight; else sum1+=dight; n/=10; index++; } ...
