题目地址: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. python tab 自动补全

    学习python,经常要使用python命令行查找一些不熟悉的使用方法等等,但是python命令行下没有自带tab补全的功能,看见别人写了tab,可以解决特此记下,以备后用 1.创建tab.py文件, ...

  2. Windows PowerShell Exit Codes

    Windows PowerShell Exit Codes PSMDTAG:FAQ: How can my script control the PowerShell exit code? Answe ...

  3. 应用js函数柯里化currying 与ajax 局部刷新dom

    直接上代码吧 最近读javascript核心概念及实践的代码 感觉很有用 备忘. <div id="request"></div> <script t ...

  4. 转 Centos下安装apahce的configure: error: APR not found. Please read the documentation解决办法

    转自: http://www.cnblogs.com/Anker/p/3355573.html 今天从Apache官网上http://httpd.apache.org/下载httpd web服务器,由 ...

  5. 46深入理解C指针之---内存分析

    一.size_t:用于安全表示长度,所有平台和系统都会解析成自己对应的长度 1.定义:size_t类型表示C中任何对象所能表示的最大长度,是个无符号整数:常常定义在stdio.h或stdlib.h中 ...

  6. 简单的 "双缓冲" 绘图的例子

    http://www.cnblogs.com/del/archive/2010/04/19/1715779.html 所谓双缓冲就是先画到内存画布(如: TBitmap), 然后再转帖到目的地. 譬如 ...

  7. AC日记——联合权值 洛谷 P1351

    题目描述 无向连通图G 有n 个点,n - 1 条边.点从1 到n 依次编号,编号为 i 的点的权值为W i ,每条边的长度均为1 .图上两点( u , v ) 的距离定义为u 点到v 点的最短距离. ...

  8. POJ 3368.Frequent values-处理数据+RMQ(ST)

    昨天写的博客删了,占坑失败,还是先把RMQ玩的6一点再去搞后面的东西.废话少说,题解题姐姐_(:з」∠)_      Frequent values Time Limit: 2000MS   Memo ...

  9. mybatis trim

    eg: select * from user <trim prefix="WHERE" prefixoverride="AND |OR"> < ...

  10. 松鼠的新家(lca)

    洛谷—— P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的 ...