hiho一下 第八十九周 Divisors
2016-03-15 19:11
197 查看
题目1 : Divisors
时间限制:10000ms单点时限:1000ms
内存限制:256MB
描述
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
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数组的方式保存。
相关文章推荐
- Python变量和对象类型速记手册
- 我和我的小伙伴们
- 蓝桥杯 牌型种数 dp解法
- bzoj 1878(离线+树状数组)
- Java获取随机数的3种方法
- iOS使用ffmpeg播放rstp实时监控视频数据流
- AutoLayout自动布局
- Beautiful String
- poj 1511 Invitation Cards (spfa + 邻接表)
- The python debugger调试(PDB)的简介
- ListView触摸事件和Item点击事件冲突解决方法
- Ubuntu14.04下安装Nessus
- 第三周项目四-穷举法解决组合问题(1)
- 13、使用DBUtils操作数据库
- Scala之主构造函数
- P364 实战练习(多线程)
- jsp 使用application.getInitParameter来获取web.xml中配置参数
- 网易2016研发工程师编程题:扫描透镜
- repo 管理多git 项目
- CodeForces 650D Zip-line(最长上升子序列)