约束个数定理:
对于一个大于1正整数n可以分解质因数:n=p1^k1*p2^k2*p3^k3.......
则约数个数x=(k1+1)*(k2+1)*(k3+1)*......
1:给你一个n求出最小的约束为n个的数。
2:求n以内约数个数最多的数,如果有多个输出最小值。
基本和上题一样。
对于一个大于1正整数n可以分解质因数:n=p1^k1*p2^k2*p3^k3.......
则约数个数x=(k1+1)*(k2+1)*(k3+1)*......
1:给你一个n求出最小的约束为n个的数。
思路:建树搜索,以每一个pi为一层建树搜索。
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
#define ll long long
const ll maxm = 1e18;
ll ans, n;
int prime[10] = { 2,3,5,7,11,13,17,19,23,29 };
void dfs(int a, int b, ll temp);
int main()
{
while (scanf("%d", &n) != EOF)
{
ans = maxm;
dfs(1, 0, 1);
printf("%I64d\n", ans);
}
return 0;
}
void dfs(int a, int b, ll temp)
{
if (a == n&&ans >= temp)
ans = temp;
if (a >= n)
return;
for (int i = 1;i <= 64;i++)
{
if (ans / prime[b] < temp)
break;
temp *= prime[b];
dfs(a*(i + 1), b + 1, temp);
}
}
2:求n以内约数个数最多的数,如果有多个输出最小值。
基本和上题一样。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define ll long long
const int ll maxm = ~0ULL;
ll n, ans, sum = 0;
int p[16] = { 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53 };
void dfs(int a, int b, ll temp);
int main()
{
while (cin >> n)
{
ans = maxm;
sum = 0;
dfs(1, 0, 1);
cout << ans << endl;
}
return 0;
}
void dfs(int a, int b, ll temp)
{
if (b >= 16)
return;
if (a >= sum)
{
if (a > sum)
{
sum = a;
ans = temp;
}
else if (a == sum&&temp < ans)
ans = temp;
}
for (int i = 1;i <= 64;i++)
{
if (temp*p[b] > n)
break;
temp *= p[b];
dfs(a*(i + 1), b + 1, temp);
}
}