hiho一下 第八十九周 Divisors
来源:互联网 发布:光环大数据怎么样 知乎 编辑:程序博客网 时间:2024/05/16 19:17
题目1 : Divisors
- 样例输入
100
- 样例输出
60
描述
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.
My Code
#include <iostream>#include <cmath>using namespace std;const int prime_numbers[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41};int size = sizeof(prime_numbers)/sizeof(int);long long N, res;int max_divisors_cnt;void DFS(long long n, int cur_divisors_cnt, int prime_idx, int ni){ if (n > N || prime_idx == size) return; if (cur_divisors_cnt > max_divisors_cnt || cur_divisors_cnt == max_divisors_cnt && n < res) { max_divisors_cnt = cur_divisors_cnt; res = n; } for (int i = 1; i <= ni; i++) { n *= prime_numbers[prime_idx]; if (n > N) break; DFS(n, cur_divisors_cnt * (i + 1), prime_idx + 1, i); }}int main(void){ while (cin >> N) { if (N == 0) { cout << 0 << endl; continue; } if (N < 0) N = -N; res = 1; max_divisors_cnt = 1; int max_cnt_of_2 = log2(N); long long n = 1; for (int i = 1; i <= max_cnt_of_2; i++) { n *= 2; DFS(n, i + 1, 1, i); } cout << res << endl; } return 0;}
Thinking
本题是一道搜索题。
首先我们需要知道一个求因子个数的定理:
假设正整数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。
这样做当然可以计算出正确结果的,但是会严重的超时。因此我们还需要其他的剪枝,这里利用一个性质:
对最小解来说一定有:若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。
为了方便,需要事先将≤41的质数都找出来,这里可以使用常用的质数判定方法,或者干脆将≤41的质数以const数组的方式保存。- hiho一下 第八十九周 Divisors
- hiho一下 第八十九周 Divisors
- hiho一下 第八周
- hiho一下 第四十九周
- hiho一下 第五十九周
- hiho一下 第九十九周
- hiho一下 第八十八周
- hiho一下 第三十九周(逆序数)
- hiho一下 第五十九周 Performance Log
- hiho一下第八周(状态压缩)
- hihocoder: hiho一下 第八十八周 88
- hiho一下 第四十九周(欧拉路的判定)49
- hiho一下 第四十九周 欧拉路·一
- hiho一下 第四十九周 -题目1 : 欧拉路·一
- hiho一下 第五十九周 题目1 : Performance Log
- hihoCoder之hiho一下 第六十九周 解题
- hiho一下 第六十九周 题目1 : HIHO Drinking Game 二分
- hiho一下 第八十八周 Coordinates (求约数)
- python入门导引
- Error:Execution failed for task ':processDebugResources'.
- printf() 参数顺序
- 利用HorizontalScrollView实现侧滑菜单
- [BZOJ3112][ZJOI2013]防守战线(单纯形)
- hiho一下 第八十九周 Divisors
- 放大镜效果
- hdu1877(栈)
- 一个和圆内接多边形有关的命题
- 穷举法解决组合问题
- Python脚本图解
- Swift异常处理:throw和rethrow
- 算法训练 幂方分解(递归)
- 2.[Gradle中文教程系列]跟我学Gradle-下载和安装Gradle