资讯详情

波浪数算法解析与高效实现

📅 2026/10/31 17:01:45 | 华诺云谱 👁 阅读
波浪数算法解析与高效实现
1. 波浪数问题解析与算法实现第一次在洛谷刷到P1112波浪数这道题时我也被题目描述绕晕了。题目要求我们找出在给定区间[l,r]内恰好有c种进制表示是波浪数的所有整数。所谓波浪数指的是在某个进制下数字的各位交替出现两个不同数字的数比如十进制下的121、1313等。1.1 波浪数的数学定义波浪数在数学上可以严格定义为对于一个k进制的n位数d1d2...dn如果满足d1≠d2且对于所有1≤i≤n-2都有didi2那么这个数就是k进制下的波浪数。例如十进制中121交替数字1和2八进制中363交替数字3和6十六进制中AFA交替数字A和F这种数的特殊之处在于同一个数值在不同进制下可能呈现出完全不同的波浪特性。比如十进制数10二进制1010波浪数交替1和0三进制101波浪数交替1和0十进制10不是波浪数1.2 问题重述与输入输出题目给出的完整输入格式是五个整数a,b,l,r,ca和b表示进制范围的下限和上限a≤k≤bl和r表示数值范围的下限和上限l≤x≤rc表示需要的波浪数表示方式的数量输出则是在[l,r]范围内恰好有c种进制在a到b范围内下是波浪数的所有整数每行一个。2. 算法设计与优化思路2.1 暴力法的局限性最直观的想法是对[l,r]范围内的每个数x枚举a到b的每个进制k检查x在k进制下是否是波浪数。这种方法虽然直接但效率极低。假设l1, r1e7a2, b36那么时间复杂度将达到O((r-l1)*(b-a1)*log(r))对于较大的r值根本无法承受。2.2 逆向思维生成所有可能的波浪数更聪明的做法是反过来思考不是检查每个数是否是波浪数而是主动生成所有在a到b进制下可能的波浪数然后统计每个数被生成了多少次。这种方法的核心优势在于波浪数的生成有明确的模式可以高效枚举避免了大量无效的进制转换和检查统计过程可以通过简单的数组计数完成具体来说对于每个进制ka≤k≤b我们生成所有k进制下的波浪数然后对于生成的每个数x如果x在[l,r]范围内就在计数数组v[x]上加1。最后我们只需要输出所有满足v[x]c的x即可。2.3 波浪数的生成算法生成k进制下的波浪数需要仔细考虑以下几点波浪数由两个不同的数字交替组成如abab...或baba...波浪数可以有任意长度但必须至少两位首位不能为0在大多数进制中具体生成步骤如下枚举第一个数字i1到k-1枚举第二个数字j0到k-1且j≠i交替使用i和j构建数字直到超过r例如在十进制下生成波浪数选择i1,j2生成12,121,1212,...选择i2,j1生成21,212,2121,...3. 代码实现与细节处理3.1 核心代码解析基于上述思路我们可以实现如下C代码#includebits/stdc.h using namespace std; int a,b,l,r,c,t,x; int v[10000005]; // 存储重数 int main(){ memset(v,0,sizeof(v)); scanf(%d%d%d%d%d,a,b,l,r,c); // 枚举所有可能的进制 for(int ka; kb; k){ // 枚举第一个数字i1到k-1 for(int i1; ik; i){ // 枚举第二个数字j0到k-1且j≠i for(int j0; jk; j){ if(i ! j){ // 确保两个数字不同 x 0; t 0; // 用于交替选择i和j while(x r){ if(t%2 0){ x x*k i; // 添加i } else { x x*k j; // 添加j } t; // 如果x在范围内计数加1 if(x l x r) v[x]; } } } } } // 输出结果 for(int il; ir; i){ if(v[i] c) printf(%d\n,i); } return 0; }3.2 关键细节说明数组大小v数组需要足够大以覆盖r的最大值。题目中r≤1e7所以声明为1e75是安全的。进制转换技巧代码中使用x x*k digit的方式直接在十进制下构建k进制数的值避免了显式的进制转换。交替模式实现使用变量t的奇偶性来决定当前应该添加i还是j简洁高效。边界处理while循环的条件是x≤r确保不会生成超出范围的数内层if检查x是否在[l,r]范围内。去重处理同一个数x可能被不同进制下的波浪数生成多次v[x]会自动累加这些情况。3.3 复杂度分析该算法的时间复杂度主要取决于波浪数的生成数量。对于每个进制k生成的波浪数数量大约为O((k^2)*logk(r))。由于k≤b且r≤1e7实际运行效率很高能够在题目要求的时间内完成。空间复杂度为O(r)主要用于存储计数数组v。4. 优化与扩展思考4.1 性能优化技巧提前终止当x超过r时立即终止当前波浪数的生成避免不必要的计算。并行处理不同进制k的波浪数生成是完全独立的可以考虑多线程并行处理。内存优化如果r非常大可以使用哈希表或稀疏数组来替代全范围的计数数组。4.2 常见错误与调试数组越界确保v数组足够大否则会导致运行时错误。整数溢出在构建x的过程中可能会超出int范围对于更大的r值应该使用long long。边界条件特别注意l1和r1e7时的特殊情况。进制范围确保a≥2且b≥a否则可能出现无效输入。4.3 算法扩展这个问题可以扩展为更一般的形式多波浪数允许三个或更多数字的交替模式。更大范围使用更高效的数据结构处理更大的数值范围。动态查询支持多次查询不同的c值而不需要重新计算。5. 实际应用与变种波浪数的概念虽然看似简单但在实际中有一些有趣的应用数字艺术波浪数因其规律的模式常被用于数字艺术和图形设计。密码学某些加密算法会利用数字的特定模式来生成密钥。数学教育帮助学生理解进制转换和数字模式的良好示例。类似的编程题目变种包括寻找特定模式的数字如回文数多进制下的数字特性判断数字模式的统计与分类提示在解决这类问题时逆向思维往往能带来意想不到的优化效果。与其被动检查每个数是否满足条件不如主动生成所有可能的解并统计。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑