题目大意:现有若干面积相同的小正方行, 给出n种面积相同的长方行, 问用最少用多少个正方行能恰好拼出n种长方行, 如n = 2, 这时最少用4个正方行可拼出2中长方形, 分别是1*4, 和2*2面积相同的长方形。
定义
对于任何正整数x,其约数的个数记做g(x).例如g(1)=1,g(6)=4.如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x为反素数.性质
性质一:一个反素数的质因子必然是从2开始连续的质数. 性质二:p=2^t1*3^t2*5^t3*7^t4.....必然t1>=t2>=t3>=....
思路:根据题意, 就是求一个数约数的一半等于n, 在这些数中取最小的, 由上面定义可知这个数就是一个反素数, 现在根据性质求出所有约数个数对应的反素数就可。求结果时, 分约数个数为奇数个和偶数个
#include <stdio.h>
#include <algorithm>
#define inf ((__int64)1<<63)-1
using namespace std;
int n = 0;
__int64 prime[22]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
__int64 num[202];
void creat(__int64 cur, int cnt, int limit, int k)//cur为当前的数, cnt为这个数约数的个数, limit为当前枚举这个质约数的上限, k为第几个质因子
{
__int64 item = cur;
if(cnt>150) return ;//当前的数不能大于10^18和约数个数不能超过150个
if(num[cnt] == inf) num[cnt] = cur;
if(num[cnt] != inf && num[cnt]>cur) num[cnt] = cur;
for(int i = 1; i<=limit; i++)
{
item *= prime[k];
if(item>(__int64)1<<60) return ;
creat(item, cnt*(i+1), i, k+1);
}
}
int main()
{
int i = 0;
__int64 ans = 0;
for(i = 1; i<=202; i++) num[i] = inf;
creat(1, 1, 75, 0);
while(scanf("%d", &n) , n)
{
if(num[2*n]>num[2*n-1]) ans = num[2*n-1];
else ans = num[2*n];
printf("%I64d\n", ans);
}
return 0;
}