题意:在给定区间[l, u]求因数最多的整数。
解题思路:素数打表, 一个个枚举求因数最多的数。
Mathematicians love all sorts of odd properties of numbers. For instance, they consider 945 to be an interesting number, since it is the first odd number for which the sum of its divisors is larger than the number itself.
To help them search for interesting numbers, you are to write a program that scans a range of numbers and determines the number that has the largest number of divisors in the range. Unfortunately, the size of the numbers, and the size of the range is such that a too simple-minded approach may take too much time to run. So make sure that your algorithm is clever enough to cope with the largest possible range in just a few seconds.
Input Specification
The first line of input specifies the number N of ranges, and each of the N following lines contains a range, consisting of a lower bound Land an upper bound U, where L and U are included in the range. L and U are chosen such that and
.
Output Specification
For each range, find the number P which has the largest number of divisors (if several numbers tie for first place, select the lowest), and the number of positive divisors D of P (where P is included as a divisor). Print the text 'Between L and H, P has a maximum of Ddivisors.', where L, H, P, and D are the numbers as defined above.
Example input
3 1 10 1000 1000 999999900 1000000000
Example output
Between 1 and 10, 6 has a maximum of 4 divisors. Between 1000 and 1000, 1000 has a maximum of 16 divisors. Between 999999900 and 1000000000, 999999924 has a maximum of 192 divisors.
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cctype>
#include<list>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
#define FOR(i, s, t) for(int i = (s) ; i <= (t) ; ++i)
#define REP(i, n) for(int i = 0 ; i < (n) ; ++i)
int buf[10];
inline long long read()
{
long long x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void writenum(int i)
{
int p = 0;
if(i == 0) p++;
else while(i)
{
buf[p++] = i % 10;
i /= 10;
}
for(int j = p - 1 ; j >= 0 ; --j) putchar('0' + buf[j]);
}
/**************************************************************/
#define MAX_N 50000
const int INF = 0x3f3f3f3f;
int isprime[MAX_N];
int prime[MAX_N];
int cnt = 0;
long long l, u;
void make_prime()
{
cnt = 0;
memset(isprime, 1, sizeof(isprime));
isprime[1] = 0;
for(long long i = 2 ; i < MAX_N ; i++)
{
if(isprime[i])
{
prime[cnt++] = i;
}
for(long long j = i * i ; j < MAX_N ; j += i)
{
isprime[j] = 0;
}
}
}
long long f(int n)
{
long long ret = 1;
for(int i = 0 ; i < cnt ; i++)
{
long long sum = 0;
while(n % prime[i] == 0)
{
sum++;
n /= prime[i];
}
ret *= (sum + 1);
}
return ret;
}
int main()
{
make_prime();
int t = read();
while(t--)
{
l = read();
u = read();
long long ans = 0;
long long tmp;
long long p;
for(long long i = l ; i <= u ; i++)
{
tmp = f(i);
if(tmp > ans)
{
ans = tmp;
p = i;
}
}
printf("Between %lld and %lld, %lld has a maximum of %lld divisors.\n", l, u, p, ans);
}
return 0;
}