题目地址: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的更多相关文章

  1. mysql基本操作【重要】

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAuYAAAVeCAIAAACyxWmSAAAgAElEQVR4nOydT0wbV/vvZzm7YXd2zI ...

随机推荐

  1. FootAwesome字体图标

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. 标准C程序设计七---66

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...

  3. HDU - 3664 Permutation Counting

    Discription Given a permutation a1, a2, … aN of {1, 2, …, N}, we define its E-value as the amount of ...

  4. Jenkins-------初探

    Jenkins 安装和使用就不说了,说一下jenkins mail的配置,稍微有点坑,记住两个地址一致 插件安装时也出问题,大天朝的防火墙真是醉了,如下 更换我大天朝的镜像站  链接如下     ht ...

  5. 提高在Xcode上的工作效率

    对于在Xcode上提高工作效率,内功在这不提,对于外力,我将它分为三类: 工具.快捷键和小技巧.主要获得的路径是通过平时积累和看 WWDC12 上的 Session 402:Working Effic ...

  6. jquery的ajax的success和fail用法

    $.ajax({ type:"POST", url: url, contentType: 'application/json;charset=utf-8', data: JSON. ...

  7. DICOM医学图像处理:Deconstructed PACS之Orthanc

    背景: 此篇博文介绍一个开源的.基于WEB的DICOM Server软件.该开源软件完全使用C++编写,不依赖于第三方数据库(内置了SQLite数据库)或其他框架,支持RESTful API设计模式. ...

  8. 【转载】GitHub中国区前100名到底是什么样的人

    转载了这篇文章: http://www.jianshu.com/p/d29cba7934c9 这篇文章真是太牛了!转载过来涨涨见识,同时好好励志一把.还有,ruanyifeng怎么长那样... 哈 另 ...

  9. 转: 写给想成为前端工程师的同学们 (from 360前端团队)

    转自:     http://www.75team.com/post/to-be-a-good-frontend-engineer.html 前端工程师是做什么的? 前端工程师是互联网时代软件产品研发 ...

  10. install nfs and share file

    介绍一下NFS的安装,以及共享文件 NFS(Net File System),通过使用NFS,可以像使用本地文件一样访问远程文件. 它主要解决了数据共享的问题,可以备份容灾. 安装配置 1.以linu ...