码迷,mamicode.com
首页 > 其他好文 > 详细

习题10-9 约数 UVa294

时间:2015-04-21 16:14:57      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:数论   约数   

1.题目描述:点击打开链接

2.解题思路:本题利用暴力搜索解决。因为题目中R-L最大不超过10000,可以直接进行搜索。并用ans,p分别标记目前找到的约数最多的个数以及对应的整数。因此关键问题是如何快速计算一个整数n的正约数的个数。

方法是这样的:可以从2开始尝试,如果n包含这个素数,那么就把它“除干净”,这样既可保证后面找到的因子均为素数,只需要枚举到sqrt(n)时即可停止。这样做的好处是不需要提前生成素数表即可得到n的唯一分解式。假设一共可以整除res次,那么累乘上res+1。注意最后如果n>1,说明最后n变为了一个素数,要再累乘上2。这样即可得到所有正约数的个数。

3.代码:

#define _CRT_SECURE_NO_WARNINGS 
#include<iostream>
#include<algorithm>
#include<string>
#include<sstream>
#include<set>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<functional>
using namespace std;

#define N 1000000000+5
#define M 100000
typedef long long ll;

ll cal(int n)
{
	int tmp = n;
	int m = sqrt(n + 0.5);//枚举到sqrt(n)即可停止
	ll cnt = 1;
	for (int i = 2; i <= m;i++)
	if (n%i == 0){
		int res = 0;
		while (n%i == 0){//除干净
			n /= i; res++;
		}
		cnt *= (res + 1);
	}
	if (n > 1)cnt *= 2;//一定要有此判断
	return cnt;
}
int main()
{
	//freopen("t.txt", "r", stdin);
	int T;
	scanf("%d", &T);
	while (T--)
	{
		ll a, b;
		scanf("%lld%lld", &a, &b);
		ll ans = 0, p = a;
		for (ll i = a; i <= b; i++)
		{
			int res = cal(i);
			if (ans < res){
				ans = res;
				p = i;
			}
		}
		printf("Between %lld and %lld, %lld has a maximum of %lld divisors.\n", a, b, p, ans);
	}
}

习题10-9 约数 UVa294

标签:数论   约数   

原文地址:http://blog.csdn.net/u014800748/article/details/45170041

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!