C语言获取第i个拉马努金数的暴力实现优化方案咨询
拉马努金数高效实现方案
直接正向逐个校验数字的方案在目标索引较大时开销会快速上升,推荐采用反向生成立方和+统计次数的方案,核心逻辑是拉马努金数的本质就是能拆分为至少两组不同正整数对立方和的数值,我们直接生成所有可能的立方和,筛选符合条件的结果即可,具体实现步骤如下:
实现步骤
- 先确定立方数遍历上限:如果要查第k个拉马努金数,先预估其大致范围,比如前10个拉马努金数都小于12万,对应立方根不足50,查前20个的话上限设为100完全足够。
- 生成所有合法立方和:遍历a从1到上限,b从a到上限(强制b≥a可以避免
1³+12³和12³+1³这种重复的相同组合),计算sum = a*a*a + b*b*b,用哈希表或者数组记录每个sum出现的次数。 - 筛选排序:把所有出现次数≥2的sum收集起来,从小到大排序,排序后的数组第
i-1位就是第i个拉马努金数。
C语言示例代码
#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> // 哈希表节点结构 typedef struct Node { uint64_t sum; int count; struct Node* next; } Node; #define HASH_SIZE 100000 Node* hash_table[HASH_SIZE] = {NULL}; // 哈希函数 uint32_t hash(uint64_t key) { return key % HASH_SIZE; } // 插入或更新立方和计数 void update_sum(uint64_t sum) { uint32_t idx = hash(sum); Node* cur = hash_table[idx]; while (cur != NULL) { if (cur->sum == sum) { cur->count++; return; } cur = cur->next; } // 新sum插入 Node* new_node = (Node*)malloc(sizeof(Node)); new_node->sum = sum; new_node->count = 1; new_node->next = hash_table[idx]; hash_table[idx] = new_node; } // 比较函数用于排序 int cmp(const void* a, const void* b) { uint64_t x = *(uint64_t*)a; uint64_t y = *(uint64_t*)b; return x > y ? 1 : -1; } // 获取第index个拉马努金数,index从1开始 uint64_t get_ramanujan(int index, int max_cube_root) { // 先生成所有立方和 for (int a = 1; a <= max_cube_root; a++) { uint64_t a3 = (uint64_t)a * a * a; for (int b = a; b <= max_cube_root; b++) { uint64_t b3 = (uint64_t)b * b * b; update_sum(a3 + b3); } } // 收集所有符合条件的拉马努金数 uint64_t res[1000] = {0}; int cnt = 0; for (int i = 0; i < HASH_SIZE; i++) { Node* cur = hash_table[i]; while (cur != NULL) { if (cur->count >= 2) { res[cnt++] = cur->sum; } cur = cur->next; } } // 排序 qsort(res, cnt, sizeof(uint64_t), cmp); // 返回结果,记得释放哈希表内存避免泄漏 uint64_t ret = res[index-1]; // 释放内存逻辑可按需补充 memset(hash_table, 0, sizeof(hash_table)); return ret; } // 测试用例 int main() { // 查第1个拉马努金数,max_cube_root设为20足够 printf("%lu\n", get_ramanujan(1, 20)); // 输出1729 printf("%lu\n", get_ramanujan(5, 60)); // 输出32832 return 0; }
效率对比
你原来的暴力方案要查到第5个拉马努金数需要校验3万多次数值,而上述方案当max_cube_root设为60时,仅需要遍历1830次a、b组合,效率提升超过16倍,目标索引越大效率优势越明显。
内容的提问来源于stack exchange,提问作者user17137852
相关产品推荐
相关产品推荐

