求不超过N的正整数中因子最多的数

2024-08-23 21:48
文章标签 正整数 因子 最多 超过

本文主要是介绍求不超过N的正整数中因子最多的数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

描述
Given an integer n, for all integers not larger than n, find the integer with the most divisors. If there is more than one integer with the same number of divisors, print the minimum one.

输入
One line with an integer n.
For 30% of the data, n ≤ 103
For 100% of the data, n ≤ 1016

输出
One line with an integer that is the answer.

样例输入
100
样例输出
60

我的程序:

#include<cmath>
#include<iostream>
using namespace std;
typedef long long ll;long prime[]={2 ,3 ,5 ,7 ,11 ,13 ,17 ,19 ,23 ,29 ,31 ,37 ,41};
ll result,n,maxDivisors;
void dfs(long t,ll now,ll divisors,ll lastNi){if(divisors > maxDivisors || (divisors==maxDivisors&&now<result)){maxDivisors = divisors;result = now;}int i = 1;while(now * pow(prime[t],i)<n && i<=lastNi){dfs(t+1,now * pow(prime[t],i),divisors*(i+1),i);i = i+1;}
}
int main()
{cin>>n;maxDivisors=0;dfs(0,1,1,100);cout<<result<<endl;return 0;
}

分析

题目大意
给定一个N,求不超过N的正整数中因子最多的数。如果有多个答案,输出最小的一个。

解题思路
本题是一道搜索题。

首先我们需要知道一个求因子个数的定理:

假设正整数n质因子分解为:

n = p1^n1 * p2^n2 * p3^n3 * ... * pk^nk

其中pi表示质因子,ni表示该质因子的数量,则有n的因子个数为:

D = (n1+1)*(n2+1)*(n3+1)* ... * (nk+1)

由此得到本题的一个基本解题思路:

枚举质因子数量,在使得n不超过N的情况下,使得D尽可能大

为了要D尽可能大,需要ni尽可能大,所以pi要尽可能小。

因此我们从最小的质数2开始枚举每一个质因子的数量ni,来计算n。

DFS(prime, now, divisors):If (prime > n) ThenReturn ;End IfIf (divisors > maxDivisors or(divisors == maxDivisors && now < result)) ThenmaxDivisors = divisorsresult = nowEnd Ifi = 0While (now * prime^i <= n) ThenDFS(next_prime, now*prime^i,divisors*(i+1))i = i + 1End While

上面这段代码是可以计算出正确结果的,但是会严重的超时。因此我们还需要其他的剪枝,这里利用一个性质:

对最小解来说一定有:若pi和pj都属于n的质因子,且pi < pj,则一定有ni≥nj,其证明如下:

假设存在nj > ni,则有:。

n' = n / pj^(nj-ni) * pi(nj-ni)

n’的质因子个数和n相比,只是交换了ni和nj的值,因此D的值不会发生变化。 而由于pj > pi,因此 n’ < n,所以 n 不是最小解。

同时由这个性质,我们可以知道当pi存在于n的质因子分解时(即ni≥1),所有比pi小的质数一定也存在于n的质因子分解中。

所以我们推断出最大可能出现的质数为41,因为2~41之间的质数相乘刚好是小于10^16 ,若再乘上43,就会超过10^16。

由此得到改进后的搜索函数:

DFS(prime, now, divisors, lastNi):If (divisors > maxDivisors or(divisors == maxDivisors && now < result)) ThenmaxDivisors = divisorsresult = nowEnd Ifi = 1   // 由于使用了当前质数才能使用后面的质数,因此这个质数至少要使用1次While (now * prime^i < n && i <= lastNi) Then// 确保i小于等于上一个质数的数量DFS(next_prime, now*prime^i,divisors*(i+1), i)i = i + 1End While

使用该剪枝后,该题也就能很快的计算出正确结果了。

为了方便,需要事先将41以内的质数都找出来,这里可以使用常用的质数判定方法,或者干脆将这一段的质数表以const数组的方式保存。

还有点需要注意的是,在计算过程中可能出现溢出的情况,需要进行处理。

这篇关于求不超过N的正整数中因子最多的数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1100589

相关文章

PTA求一批整数中出现最多的个位数字

作者 徐镜春 单位 浙江大学 给定一批整数,分析每个整数的每一位数字,求出现次数最多的个位数字。例如给定3个整数1234、2345、3456,其中出现最多次数的数字是3和4,均出现了3次。 输入格式: 输入在第1行中给出正整数N(≤1000),在第二行中给出N个不超过整型范围的非负整数,数字间以空格分隔。 输出格式: 在一行中按格式“M: n1 n2 ...”输出,其中M是最大次数,n

线性因子模型 - 独立分量分析(ICA)篇

序言 线性因子模型是数据分析与机器学习中的一类重要模型,它们通过引入潜变量( latent variables \text{latent variables} latent variables)来更好地表征数据。其中,独立分量分析( ICA \text{ICA} ICA)作为线性因子模型的一种,以其独特的视角和广泛的应用领域而备受关注。 ICA \text{ICA} ICA旨在将观察到的复杂信号

C语言练习题之 数组中出现次数超过一半的数

题目描述 给一个长度为 n 的数组,数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 例如输入一个长度为9的数组[1,2,3,2,2,2,5,4,2]。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。 数据范围:n≤50000,数组中元素的值0≤val≤10000 要求:空间复杂度:O(1),时间复杂度O(n) 输入描述: 保证数组输入非空,且保证有

【CSS】flex布局 - 左边超过打点, 右边完整展示

场景:宽度一定的情况下右边自适应,左边被挤压。 需要的效果如下: flex 的三个参数分别对应:flex-grow、flex-shrink、flex-basis。 flex-grow:定义项目的放大比例,默认为0。即如果存在剩余空间,也不放大。flex-shrink:定义项目的缩小比例,默认为1。即如果空间不足,该项目将缩小。flex-basis:定义在分配多余空间之前,项目占据的主轴空间。

HDU2521(求因子个数)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2521 解题思路: 数据量不大,直接O(n)遍历,对每个数求其因子个数,找出最大的即可。 完整代码: #include <functional>#include <algorithm>#include <iostream>#include <fstream>#includ

连分数因子分解法——C语言实现

参考网址:连分数分解法寻找整数的因子(Python)-CSDN博客 大数运算:C语言实现 大数运算 加减乘除模运算 超详细_64编程 加减乘除取模 复杂运算-CSDN博客 ‌连分数因子分解法‌是一种用于大整数因子分解的算法,它是计算数论中的一个重要方法。连分数因子分解法通过寻找x2≡y2 (mod p)x2≡y2 (mod p)的形式来分解N。具体来说,这种方法涉及到计算N的简单连分数展开,并

js算法题,给任意一个偶数,找出他的所有的质数因子

/*给任意一个偶数,找出他的所有的质数因子*/ function primeFactor(n){     var factors=[],            divistor=2;     if(typeof n !=='number'||!Number.isInteger(n)){          return 0;     }; //如果不是偶数返回0,如果是0,返回0

报错处理:超过Uobject最大数量

处理方式 一、打包时项目中设置游戏中UObject的最大数量为100000000 二、打包后的配置文件中设置 打包路径: 一厅统管\Windows\YZ_YTTG\Saved\Config\Windows\Engine.ini文件下添加配置文件 [/Script/Engine.GarbageCollectionSettings] gc.MaxObjectsInEditor=100000000

【WPS Excel】复制表格时,提示“图片太大,超过部份将被截去“ 问题

WPS表格 2019版本 升级到 WPS最新版 WPS-支持多人在线协作编辑Word、Excel和PPT文档_WPS官方网站 使用最新版就能够解决这个问题,如果仍旧无法解决可以勾选如下配置 重启Excel解决。 请勾选:文件 - 选项 - 编辑 - 不提示且不压缩文件中的图像

判断两个yaw角度之差是否超过了90度

一. 判断两个yaw角度之差是否超过了90度 要判断两个 yaw 角度之差是否超过 90 度,你可以通过计算这两个角度的差值,并将其归一化为 [-180, 180] 的范围内。接着,只需判断该差值的绝对值是否大于 90 度。 实现步骤: 计算角度差:两个角度的差值可以通过直接相减得到,但需要将结果限制在 [-180, 180] 范围内,因为角度是周期性的。归一化到 [-180, 180] 范