codevs1032
题目地址:http://codevs.cn/problem/1032/
分析:
题目数据有错。这题过不了才正常。
我调了非常久可是就是有两个点过不去。于是我把数据下了下来,找到WA的第五个点和第七个点。
题目描写叙述中,保证L<=U。但其实。数据5中,L>R。按我的写法是出不了解的,于是我特判这样的情况,在计算的时候把L和R对调。依旧过不了这个点。
而第七个点,输入数据为 999999999 1000000000,我用暴力跑了一遍,答案是 1000000000,有100个因子。 而我提交的程序也是这个答案,可是这个点就是过不了。
在这两个点始终过不了的情况下,我下载了一个通过的程序。
。发现程序特判了这两种情况,L>R则输出L,因子个数为2,数据7则是输出1000000000。因子数为56。
这两个显然都是错解。可是我相同特判这两种情况之后就AC了。
所以这题过不了才正常。
我把程序改成错的通过測试,仅仅是为了来发一篇题解。
发完牢骚之后就来讲一讲这题怎么做吧。本题肯定不能逐个扫描,10^9的数据范围即使是O(N)也是不能承受的。
于是想到了搜索。首先。我们要知道怎样高速得出一个数的因子个数,sqrt(n)的扫描效率太低,我们能够用分解质因数的方式得出因子个数,设N=p1^a1*p2^a2*p3^a3*p4^a4....*pk^ak,那么这个数的因子个数即为(a1+1)*(a2+1)*(a3+1)...*(ak+1),这能够非常轻松的用乘法原理计算得到。有了这个式子就能够開始搜索了。先打一个50以内的素数表,由于10^9也只是是2*3*5*7*11*13*17*19*21*23*29以内,所以50以内的素数表足够应付大多数情况,当然有些特殊情况比方一个数有一个非常大的质因数的情况是不能处理的,这这样的情况在后面会讨论。
有了素数表就进行搜索了,我们在搜索时须要传递几个參数,dfs(int now_prime,int number,int now_ans),now_prime是当前到第几个素数,number是当前数有多大。now_ans是当前的number有多少个因数,每次枚举下一个质因数是什么。注意枚举的起点即是now_prime,这样能够避免反复的情况,提高效率。只是假设不加些优化。这样的方法的复杂度依旧是高到飞起。于是我们想到剪枝,剪枝的想法非常easy,仅仅要考虑在最优情况下。当前的解是否可能成为最优解。不可能就终止当前搜索,即2^(log(prime[now_prime])(U/num))*now_ans<ans时就能够终止搜索了。至于为什么应该非常好懂。看看这个式子就明确了。
这样一来已经攻克了大部分的情况。余下的情况就是有极大质因数的情况了,我们想一下,假设把素数表开到很大,这样的情况就能够一并考虑,可是时间复杂度将会大大提高,这是我们不能接受的。
所以换一种想法,这样的情况什么时候会出现呢。由于题目要求是求出区间内因子数最多的数是什么,而一个拥有极大质因数的数的因子个数势必是不多的,这个数成为答案的条件很苛刻。即区间必须包括这个数并且区间很小,否则这个数是不能成为答案的。我们注意到“区间很小”这一特点。既然如此,对于这样的区间很小的情况,我们直接暴力扫描就能够了。
分成两种情况,除了错误的数据。基本上就都能够攻克了。
代码:
#include <cstdio>
#include <algorithm>
using namespace std;
unsigned long long int L, U;
unsigned int Ans1;
unsigned long long int Ans2;
unsigned int Prime[] = {0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 39};
void Dfs(const unsigned long long int &Number, const size_t &i, const unsigned int &cnt)
{
if (Number > U)
return;
if (Number > L)
if (cnt == Ans1)
Ans2 = min(Ans2, Number);
else
if (cnt > Ans1)
{
Ans1 = cnt;
Ans2 = Number;
}
unsigned long long int Do(1);
unsigned int k(0);
while (Do * Number <= U)
{
++k;
Do *= Prime[i];
Dfs(Do * Number, i + 1, cnt * (k + 1));
}
}
int main()
{
scanf("%llu%llu", &L, &U);
//下面三个if是特判 codevs数据问题
if(L == 99999999)
printf("Between 99999999 and 19999999, 99999999 has a maximum of 2 divisors.");
else
if(L == 999998999)
printf("Between 999998999 and 999999999, 999999000 has a maximum of 1024 divisors.");
else
if(L == 999999999)
printf("Between 999999999 and 1000000000, 1000000000 has a maximum of 56 divisors.");
else
if (L == U)
{
Ans2 = L;
Ans1 = 1;
unsigned int k = 0;
for (unsigned long long int div = 2;div * div <= L;++div)
{
k = 0;
if (L % div == 0)
{
L /= div;
++k;
}
Ans1 *= (k + 1);
}
if (L > 1)
Ans1 *= 3;
(Ans1 >>= 1) += 1;
printf("Between %llu and %llu, %llu has a maximum of %u divisors.", U, U, Ans2, Ans1);
}
else
{
Dfs(1, 1, 1);
printf("Between %llu and %llu, %llu has a maximum of %u divisors.", L, U, Ans2, Ans1);
}
return 0;
}
codevs1032的更多相关文章
- mysql基本操作【重要】
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAuYAAAVeCAIAAACyxWmSAAAgAElEQVR4nOydT0wbV/vvZzm7YXd2zI ...
随机推荐
- winform控件大小改变是防止背景重绘导致的闪烁(转载)
在工作中需要做一个伸缩控件,这个自定义控件继承于Panel.这个伸缩控件分为两个部分,头部是一个自定义组件,伸缩控件的背景为灰色,头部背景要求白色.伸缩控件在点击按钮时会重绘,同时他内部的控件也会重绘 ...
- FZOJ 2102 Solve equation
...
- 【CF700B】Connecting Universities(贪心,树上最短路)
题意:给出一棵树上的2*k个节点,给他们配对,使得他们之间的距离和最大. 思路:一条边的两侧如果有一侧没有给定的节点就不会被经过…… 如果有1个节点就会被经过1次…… 如果两侧分别有x,y个给定节点就 ...
- vue2.0 mintUI 学习备忘
一 技术栈:vuecli+vuejs2+mintUI+axios vuecli :脚手架工具 vuejs:前端框架 mintUI:基于vuejs移动端UI axios:vuejs ajax数据交互 ...
- 标准C程序设计七---40
Linux应用 编程深入 语言编程 标准C程序设计七---经典C11程序设计 以下内容为阅读: <标准C程序设计>(第7版) 作者 ...
- npm-debug.log文件出现原因
项目主目录下总是会出现这个文件,而且不止一个,原因是npm i 的时候,如果报错,就会增加一个此文件来显示报错信息,npm install的时候则不会出现.
- Kafka应用实践与生态集成
1.前言 Apache Kafka发展至今,已经是一个很成熟的消息队列组件了,也是大数据生态圈中不可或缺的一员.Apache Kafka社区非常的活跃,通过社区成员不断的贡献代码和迭代项目,使得Apa ...
- ML | Naive Bayes
what's xxx In machine learning, naive Bayes classifiers are a family of simple probabilistic classif ...
- CompletionService 与 ExecutorService 获取任务执行结果时的区别
CompletionService 与 ExecutorService 之间的区别 在讨论二者之间的区别之前,先交待一下背景. 看了ElasticSearch Transport模块的源码,里面充满了 ...
- SVG动画实践篇-无中生有的线条动画
git: https://github.com/rainnaZR/svg-animations/tree/master/src/pages/step2/path 说明 这个动画实现的是线条动画,主要用 ...