当前位置: 首页 > news >正文

反素数c++

先上代码

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

ll n;

ll p[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};

int maxd,maxval;

void dfs(int pl,ll tmp,int num,int  up){

    if((num>maxd)||(num==maxd&&maxval>tmp)){

        maxd=num;

        maxval=tmp;

    }

    if(pl==16) return;

    for(int i=1;i<=up;i++){

        if(tmp*p[pl]>n) return;

        tmp*=p[pl];

        dfs(pl+1,tmp,num*(i+1),i);

    }

}

int main(){

    cin>>n;

    dfs(0,1,1,63);

    cout<<maxval<<endl;

    return 0;

}

代码解析:寻找不超过n的反素数

这段代码是用来寻找不超过给定正整数n的反素数(antiprime number)。反素数是指在一个特定范围内拥有最多因数的数中最小的那个。

反素数的定义和性质

反素数具有以下性质:

  1. 它是范围内因数个数最多的数

  2. 如果有多个数具有相同的最大因数个数,则选择其中最小的一个

  3. 反素数的质因数分解中,质数是从小到大排列的,且指数是单调不增的

代码结构分析

1. 全局变量和预处理

typedef long long ll;
ll n;
ll p[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
int maxd, maxval;
  • p[]数组存储了前16个质数(2到53)

  • maxd记录当前找到的最大因数个数

  • maxval记录对应的数值

2. 深度优先搜索函数dfs

void dfs(int pl, ll tmp, int num, int up) {if((num>maxd)||(num==maxd&&maxval>tmp)) {maxd = num;maxval = tmp;}if(pl == 16) return;for(int i=1; i<=up; i++) {if(tmp*p[pl] > n) return;tmp *= p[pl];dfs(pl+1, tmp, num*(i+1), i);}
}

参数说明:

  • pl:当前考虑的质数在p[]中的索引

  • tmp:当前生成的数值

  • num:当前数值的因数个数

  • up:当前质数的最大可能指数(保证指数单调不增)

函数逻辑:

  1. 检查当前数值是否比已记录的最优解更好(因数更多,或因数相同但数值更小)

  2. 如果已经考虑完所有质数(16个),则返回

  3. 尝试为当前质数分配指数i(从1到up)

    • 确保乘积不超过n

    • 递归处理下一个质数,更新数值、因数个数,并限制下一个质数的指数不超过当前i

3. 主函数

cpp

复制

下载

int main() {cin >> n;dfs(0, 1, 1, 63);cout << maxval << endl;return 0;
}
  • 读取输入的n

  • 从第一个质数(索引0)开始搜索,初始数值为1,因数个数为1,初始指数上限设为63(足够大)

  • 输出找到的反素数

算法原理

  1. 因数个数计算:一个数的因数个数等于其质因数分解各指数加1的乘积。例如,12=2²×3¹,因数个数为(2+1)×(1+1)=6。

  2. 贪心策略:为了找到因数最多且数值最小的数,我们:

    • 优先使用较小的质数

    • 确保质数的指数是单调不增的(更大的质数指数不超过前面的)

  3. 剪枝优化

    • 当当前乘积超过n时停止继续尝试

    • 限制后续质数的指数不超过前一个质数的指数

示例分析

假设n=10:

  1. 搜索过程会尝试以下组合:

    • 2^1 = 2 (因数2)

    • 2^2 = 4 (因数3)

    • 2^3 = 8 (因数4)

    • 3^1 = 3 (因数2)

    • 2^1×3^1 = 6 (因数4)

    • 其他组合会超过10

  2. 最终找到6和8都有4个因数,选择较小的6

复杂度分析

  • 时间复杂度:O(2^k),其中k是质数个数(这里k=16),但由于剪枝和指数限制,实际运行很快

  • 空间复杂度:O(k)递归深度

这段代码高效地利用了反素数的数学性质和DFS剪枝策略,能够在合理时间内找到不超过n的最大反素数。

进行递归时要注意手动模拟理解代码,例如n=18时,一次进行这样的搜索

1.  2^1 (因数2)

2.  2^1*3^1(因数4)

3.  2^2 (因数3)

4.  2^2*3^1(因数6)

5.  2^3 (因数4)

如此得到答案12

自己这样模拟一遍便能理解代码是如何操作并进行筛选出最终答案了

相关文章:

  • 云原生--基础篇-4--CNCF-1-云原生计算基金会(云原生生态发展和目标)
  • 【文件上传/下载Java+vue3——MQ】
  • vue3新增特性
  • KUKA机器人KR 3 D1200 HM介绍
  • [Android]豆包爱学v4.5.0小学到研究生 题目Ai解析
  • Postman下载安装与使用汉化版教程
  • 桌面我的电脑图标不见了怎么恢复 恢复方法指南
  • 虚无隧穿产生宇宙(true nothing tunneling) 是谁提出的
  • MAC系统下完全卸载Android Studio
  • hbuilderx云打包生成的ipa文件如何上架
  • 路由器转发规则设置方法步骤,内网服务器端口怎么让异地连接访问的实现
  • 【白雪讲堂】[特殊字符]内容战略地图|GEO优化框架下的内容全景布局
  • 【AI】SpringAI 第四弹:接入本地大模型 Ollama
  • 如何正确选择培养基种类
  • PaddlePaddle线性回归详解:从模型定义到加载,掌握深度学习基础
  • MacOS 10.15上能跑大语言模型吗?
  • HCIP(OSPF)(3)
  • qt报“use multi-arg instead [clazy-qstring-arg]”警告的解决方法
  • QML FontDialog:使用FontDialog实现字体选择功能
  • 如何Ubuntu 22.04.5 LTS 64 位 操作系统部署运行SLAM3! 详细流程
  • 创单次出舱活动时长世界纪录,一组数据盘点神十九乘组工作成果
  • 世界读书日丨人均一年超10本!你达到上海平均阅读水平了吗
  • 深一度|坚守17年,这件事姚明就算赔钱也在继续做
  • C909飞机开启越南商业运营
  • 因在罗博特科并购项目中执业违规,东方证券、国浩所均遭警示
  • 马上评丨直播员工上班?职场不是“楚门的世界”