hdu 4133

由于上一次做的线段树用到反素数,觉得很神奇,所以在这学习了一下。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4133

关于反素数的定义参见百度百科:http://baike.baidu.com/view/2621997.htm

 

关键还是代码,参照反素数性质剪枝搜索。关于我的理解都写在代码注释里了。代码就是百度百科的

#include <stdio.h>
#include <string.h>

/*性质一:一个反素数的质因子必然是从2开始连续的质数.*/

const __int64 prime[16] = {1,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};

__int64 maxsum, bestnum, n;//maxsum最优解时的因数个数, bestnum是最优解

/*
num:当前枚举到的数,k:枚举到的第k大的质因子;sum:该数的约数个数;limit:质因子个数上限;
*/

void dfs(__int64 num, __int64 k, __int64 sum, __int64 limit)
{
	if (sum > maxsum)   //如果约数个数更多,将最优解更新为当前数;
	{
		maxsum = sum;
		bestnum = num;
	}
	else if (sum == maxsum && bestnum > num)
	{
		bestnum = num; //如果约数个数相同,将最优解更新为较小的数;
	}
	if (k>15)//枚举的数超过 prime数组元素个数。 
	{
		return;
	}
	__int64 temp = num, i;
	for (i=1; i<=limit; i++)//利用性质2:p=2^t1*3^t2*5^t3*7^t4.....必然t1>=t2>=t3>=....
	{
		if (temp * prime[k] > n)
		{
			break;
		}
		
		/*
			temp为乘上一个第k个质因数的值 
			k+1是指向下一个质因数
			sum*(i+1): 假设 p=2^t1*3^t2*5^t3*7^t4,则他的约数个数是(t1+1)*(t2+1)*(t3+1)*(t4+1)
			加一的原因自己想想应该很简单 
			所以sum*(i+1)就是temp的约数个数 
			i就是下一个质因数的上限,就是性质2;
		*/
		 
		temp = temp * prime[k];
		dfs(temp, k+1, sum * (i+1), i); 
	}
}
int main()
{
	int T, Cas = 1;
	scanf("%d", &T);
	while (T--)
	{
		maxsum = 0;
		bestnum = 0;
		scanf("%I64d", &n);
		dfs(1, 1, 1, 50); //k要从1开始,因为prime[0] = 1;1不是质因数 
		printf("Case #%d: %I64d\n", Cas++, bestnum);
	}
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值